53

我有两个 zip 文件,它们都可以用 Windows Explorer 和 7-zip 很好地打开。

但是,当我使用 Python 的 zipfile 模块 [ zipfile.ZipFile("filex.zip") ] 打开它们时,其中一个会被打开,但另一个会出现错误“ BadZipfile: File is not a zip file”。

通过使用 7-Zip 打开它并查看其属性(例如 7Zip.ZIP),我确保后者是一个有效的 Zip 文件。当我用文本编辑器打开文件时,前两个字符是“PK”,表明它确实是一个 zip 文件。

我正在使用 Python 2.5,并且真的不知道如何去做。我在 Windows 和 Ubuntu 上都试过了,两个平台上都存在问题。

更新: Windows 上 Python 2.5.4 的追溯:

Traceback (most recent call last):
File "<module1>", line 5, in <module>
    zipfile.ZipFile("c:/temp/test.zip")
File "C:\Python25\lib\zipfile.py", line 346, in init
    self._GetContents()
File "C:\Python25\lib\zipfile.py", line 366, in _GetContents
    self._RealGetContents()
File "C:\Python25\lib\zipfile.py", line 378, in _RealGetContents
    raise BadZipfile, "File is not a zip file"
BadZipfile: File is not a zip file

基本上,当_EndRecData调用该函数以从“中央目录结尾”记录中获取数据时,评论长度检查失败 [endrec[7] == len(comment)]。

函数中locals的值_EndRecData如下:

 END_BLOCK: 4096,
 comment: '\x00',
 data: '\xd6\xf6\x03\x00\x88,N8?<e\xf0q\xa8\x1cwK\x87\x0c(\x82a\xee\xc61N\'1qN\x0b\x16K-\x9d\xd57w\x0f\xa31n\xf3dN\x9e\xb1s\xffu\xd1\.....', (truncated)
 endrec: ['PK\x05\x06', 0, 0, 4, 4, 268, 199515, 0],
 filesize: 199806L,
 fpin: <open file 'c:/temp/test.zip', mode 'rb' at 0x045D4F98>,
 start: 4073
4

9 回答 9

20

名为 file 的文件可能会混淆 python - 尝试将其命名为其他名称。如果它仍然不起作用,请尝试以下代码:

def fixBadZipfile(zipFile):  
 f = open(zipFile, 'r+b')  
 data = f.read()  
 pos = data.find('\x50\x4b\x05\x06') # End of central directory signature  
 if (pos > 0):  
     self._log("Trancating file at location " + str(pos + 22)+ ".")  
     f.seek(pos + 22)   # size of 'ZIP end of central directory record' 
     f.truncate()  
     f.close()  
 else:  
     # raise error, file is truncated  
于 2012-07-08T18:17:45.853 回答
12

我遇到了同样的问题。我的问题是它是 gzip 而不是 zip 文件。我切换到课堂gzip.GzipFile,它就像一个魅力。

于 2013-09-18T13:39:45.230 回答
12

astronautlevel 的解决方案适用于大多数情况,但 Zip 中的压缩数据和 CRC 也可以包含相同的 4 个字节。您应该执行rfind(not find),查找 pos+20,然后将写入添加\x00\x00到文件末尾(告诉 zip 应用程序“comments”部分的长度为 0 字节长)。


    # HACK: See http://bugs.python.org/issue10694
    # The zip file generated is correct, but because of extra data after the 'central directory' section,
    # Some version of python (and some zip applications) can't read the file. By removing the extra data,
    # we ensure that all applications can read the zip without issue.
    # The ZIP format: http://www.pkware.com/documents/APPNOTE/APPNOTE-6.3.0.TXT
    # Finding the end of the central directory:
    #   http://stackoverflow.com/questions/8593904/how-to-find-the-position-of-central-directory-in-a-zip-file
    #   http://stackoverflow.com/questions/20276105/why-cant-python-execute-a-zip-archive-passed-via-stdin
    #       This second link is only losely related, but echos the first, "processing a ZIP archive often requires backwards seeking"
    content = zipFileContainer.read()
    pos = content.rfind('\x50\x4b\x05\x06') # reverse find: this string of bytes is the end of the zip's central directory.
    if pos>0:
        zipFileContainer.seek(pos+20) # +20: see secion V.I in 'ZIP format' link above.
        zipFileContainer.truncate()
        zipFileContainer.write('\x00\x00') # Zip file comment length: 0 byte length; tell zip applications to stop reading.
        zipFileContainer.seek(0)

    return zipFileContainer
于 2014-02-24T18:52:20.327 回答
3

我遇到了同样的问题,并且能够为我的文件解决这个问题,请参阅我在 zipfile 无法处理某种类型的 zip 数据?

于 2011-09-17T21:03:04.513 回答
1

显示您从 Python 获得的完整回溯——这可能会提示具体问题是什么。未回答:什么软件产生了坏文件,在什么平台上?

更新:Traceback 表示在检测文件中的“中央目录结束”记录时遇到问题 - 请参阅从 C:\Python25\Lib\zipfile.py 的第 128 行开始的函数 _EndRecData

建议:
(1)通过上面的函数进行追踪
(2)在最新的Python上试试
(3)回答上面的问题。
(4) 阅读本文和其他任何google("BadZipfile: File is not a zip file")似乎相关的内容

于 2010-06-21T11:16:22.303 回答
1

有时存在包含损坏文件的 zip 文件,并且在解压缩 zip 时会出现 badzipfile 错误。但是有像 7zip winrar 这样的工具可以忽略这些错误并成功解压缩 zip 文件。您可以创建一个子进程并使用此代码解压缩您的 zip 文件,而不会出现 BadZipFile 错误。

import subprocess
ziploc = "C:/Program Files/7-Zip/7z.exe" #location where 7zip is installed
cmd = [ziploc, 'e',your_Zip_file.zip ,'-o'+ OutputDirectory ,'-r' ] 
sp = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
于 2019-01-31T09:53:02.597 回答
0

您是否尝试过更新的 python,或者如果太麻烦,只需更新的 zipfile.py?我已经成功地将 Python 2.6.2(当时最新)的 zipfile.py 副本与 Python 2.5 一起使用,以便打开 Py2.5s zipfile 模块不支持的一些 zip 文件。

于 2010-06-22T07:03:55.897 回答
0

在某些情况下,您必须确认 zip 文件是否实际上是 gzip 格式。对我来说就是这种情况,我通过以下方式解决了它:

import requests
import tarfile
url = ".tar.gz link"
response = requests.get(url, stream=True)
file = tarfile.open(fileobj=response.raw, mode="r|gz")
file.extractall(path=".")
于 2021-10-19T09:08:43.950 回答
0

I faced this problem and was looking for a good and clean solution; But there was no solution until I found this answer. I had the same problem that @marsl (among the answers) had. It was a gzipfile instead of a zipfile in my case.

I could unarchive and decompress my gzipfile with this approach:

with tarfile.open(archive_path, "r:gz") as gzip_file:
    gzip_file.extractall()
于 2020-12-27T20:19:31.337 回答