我有一个Python
脚本,我需要提取ZIP文件的内容。但是,zip文件的大小超过6GB。
有很多关于zlib
和zipfile
模块的信息,但是,我无法找到适用于我的案例的单一方法。
我有代码:
with zipfile.ZipFile(fname, "r") as z:
try:
log.info("Extracting %s " %fname)
head, tail = os.path.split(fname)
z.extractall(folder + "/" + tail)
except zipfile.BadZipfile:
log.error("Bad Zip file")
except zipfile.LargeZipFile:
log.error("Zip file requires ZIP64 functionality but that has not been enabled (i.e., too large)")
except zipfile.error:
log.error("Error decompressing ZIP file")
我知道我需要将allowZip64
设置为true
,但我不确定如何执行此操作。然而,即使是这样,也不会抛出LargeZipFile
异常,而是BadZipFile
异常。我不明白为什么。
另外,这是处理提取6GB zip存档的最佳方法吗?
更新:
修改BadZipfile
例外:
except zipfile.BadZipfile as inst:
log.error("Bad Zip file")
print type(inst) # the exception instance
print inst.args # arguments stored in .args
print inst
所示:
<class 'zipfile.BadZipfile'>
('Bad magic number for file header',)
更新#2:
完整的追溯显示
BadZipfile Traceback (most recent call last)
<ipython-input-1-8d34a9f58f6a> in <module>()
6 for member in z.infolist():
7 print member.filename[-70:],
----> 8 f = z.open(member, 'r')
9 size = 0
10 while True:
/Users/brspurri/anaconda/python.app/Contents/lib/python2.7/zipfile.pyc in open(self, name, mode, pwd)
965 fheader = struct.unpack(structFileHeader, fheader)
966 if fheader[_FH_SIGNATURE] != stringFileHeader:
--> 967 raise BadZipfile("Bad magic number for file header")
968
969 fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
BadZipfile: Bad magic number for file header
运行代码:
import sys
import zipfile
with open(zip_filename, 'rb') as zf:
z = zipfile.ZipFile(zf, allowZip64=True)
z.testzip()
doesn't output anything.
答案 0 :(得分:7)
问题是您的zip文件已损坏。我可以在下面添加有关腐败的更多细节,但首先是实用的东西:
您可以使用this code snippet告诉您存档中的哪个成员已损坏。但是,print z.testzip()
已经告诉你同样的事情了。命令行上的zip -T
或unzip
也应该为您提供具有适当详细程度的信息。
那么,你怎么办呢?
嗯,显然,如果你能得到一份未经破坏的文件副本,那就去做吧。
如果没有,如果你想跳过坏文件并提取其他所有内容,这很容易 - 大多数代码与上面链接的代码段相同:
with open(sys.argv[1], 'rb') as zf:
z = zipfile.ZipFile(zf, allowZip64=True)
for member in z.infolist():
try:
z.extract(member)
except zipfile.error as e:
# log the error, the member.filename, whatever
Bad magic number for file header
异常消息表示zipfile
能够成功打开zip文件,解析其目录,查找成员的信息,在归档中寻找该成员,并阅读标题该成员 - 所有这些意味着您可能在这里没有与zip64相关的问题。但是,当它读取该标题时,它没有PK\003\004
的预期“魔术”签名。这意味着存档已损坏。
腐败恰好恰好是4294967296这一事实非常强烈地暗示你在链的某处有一个64位问题,因为那正是2 ** 32。
命令行zip
/ unzip
工具有一些解决方法可以解决导致此类问题的腐败的常见原因。看起来这些变通办法可能适用于此存档,因为您收到警告,但所有文件都显然已恢复。 Python的zipfile
库没有这些解决方法,我怀疑你想自己编写zip
- 自己处理代码......
然而,这确实为另外两种可能性敞开了大门:
首先,zip
可以使用-F
-FF
标记为您修复 zipfile。 (阅读联机帮助页,或zip -h
,或者在SuperUser等网站上询问是否需要帮助。)
如果所有其他方法都失败了,您可以从Python运行unzip
工具,而不是使用zipfile
,如下所示:
subprocess.check_output(['unzip', fname])
当然,这比zipfile
模块给你的灵活性和功率要低得多 - 但你无论如何都没有使用任何灵活性;你只是打电话给extractall
。