在对unzip(1L)
感到沮丧之后,我一直在尝试创建一个脚本,该脚本将解压缩并打印出来自stdin的zip存档中的所有文件的原始数据。我目前有以下工作:
import sys, zipfile, StringIO
stdin = StringIO.StringIO(sys.stdin.read())
zipselect = zipfile.ZipFile(stdin)
filelist = zipselect.namelist()
for filename in filelist:
print filename, ':'
print zipselect.read(filename)
当我尝试添加验证以检查它是否真的是一个zip文件时,它不喜欢它。
...
zipcheck = zipfile.is_zipfile(zipselect)
if zipcheck is not None:
print 'Input is not a zip file.'
sys.exit(1)
...
结果
File "/home/chris/simple/zipcat/zipcat.py", line 13, in <module>
zipcheck = zipfile.is_zipfile(zipselect)
File "/usr/lib/python2.7/zipfile.py", line 149, in is_zipfile
result = _check_zipfile(fp=filename)
File "/usr/lib/python2.7/zipfile.py", line 135, in _check_zipfile
if _EndRecData(fp):
File "/usr/lib/python2.7/zipfile.py", line 203, in _EndRecData
fpin.seek(0, 2)
AttributeError: ZipFile instance has no attribute 'seek'
我认为它不能寻求,因为它不是文件,因此?
很抱歉,如果这是显而易见的,这是我第一次使用Python“去”。
答案 0 :(得分:3)
您应该将stdin
传递给is_zipfile
,而不是zipselect
。 is_zipfile
获取文件或文件对象的路径,而不是ZipFile
。
请参阅the zipfile.is_zipfile documentation
ZipFile
无法搜索是正确的,因为它不是文件。它是一个存档,因此它可以包含许多文件。
答案 1 :(得分:1)
完全在记忆中这样做需要一些工作。 AttributeError
消息表示is_zipfile
方法正在尝试使用您提供的文件句柄的seek
方法。但是标准输入是不可搜索的,因此它的文件对象没有seek
方法。
如果你真的,真的无法暂时将文件存储在磁盘上,那么你可以在内存中缓冲整个文件(你需要强制执行大小限制以确保安全性),然后实现一些看起来像“鸭子”的代码并且像一个可搜索的文件对象,但实际上只是在内存中使用字节串。
你有可能只为is_zipfile
作弊和缓冲足够的数据来完成它的工作,但我似乎记得ZIP的目录是在文件的末尾。我可能错了。
答案 2 :(得分:0)
你的2011 python2片段是:StringIO.StringIO(sys.stdin.read())
2018年,python3程序员可能会将其表示为:io.StringIO(...)。
你想要的是以下python3片段:io.BytesIO(...)。
当使用requests
模块从Web服务器下载二进制ZIP文件时,这对我来说很有用:
zf = zipfile.ZipFile(io.BytesIO(req.content))