我正在尝试解决在Python中从
stdin
读取zip文件的问题,但我不断遇到问题。我想要的是能够运行 cat test.xlsx | python3 test.py
并创建一个有效的 zipfile.ZipFile
对象,而无需先编写临时文件(如果可能)。
我最初的方法是这样的,但是
ZipFile
抱怨文件不可查找,
import sys
import zipfile
zipfile.ZipFile(sys.stdin)
所以我改变了它,但现在它抱怨这不是一个有效的zip文件:
import io
import sys
import zipfile
zipfile.ZipFile(io.StringIO(sys.stdin.read()))
可以在不将 zip 写入临时文件的情况下解决此问题吗?
Zip 文件是二进制数据,而不是 UTF-8 编码的文本。如果不立即遇到
str
错误,您将无法使用 sys.stdin.read()
将文件读入 UnicodeDecodeError: 'utf-8' codec can't decode byte ...
。
buffer
对象以将标准输入读取为原始 bytes
。将其与 BytesIO
配对以获得内存中可查找的类文件对象:
zipfile.ZipFile(io.BytesIO(sys.stdin.buffer.read()))
或者,如果您提供可查找的标准输入(例如,通过重定向标准输入而不是从管道流式传输),则可以直接对
sys.stdin.buffer
进行操作:
zipfile.ZipFile(sys.stdin.buffer)
与类似的东西配对
python3 test.py <test.xlsx
seekable
方法,根据 stdin 是否可在两者之间进行选择:
if sys.stdin.buffer.seekable():
zip_file = zipfile.ZipFile(sys.stdin.buffer)
else:
buffer = io.BytesIO(sys.stdin.buffer.read())
zip_file = zipfile.ZipFile(buffer)
print(zip_file.filelist)