9

我在尝试解压缩 zip 文件时遇到了这个问题。

--zipfile.is_zipfile(my_file)总是返回 False,即使 UNIX 命令 unzip 处理得很好。此外,当我尝试这样做时,zipfile.ZipFile(path/file_handle_to_path)我得到了同样的错误

--file命令返回Zip archive data, at least v2.0 to extractless在它显示的文件上使用:

PKZIP for iSeries by PKWARE Length Method Size Cmpr Date Time CRC-32 Name 2113482674 Defl:S 204502989 90% 2010-11-01 08:39 2cee662e myfile.txt 2113482674 204502989 90% 1 file

有什么想法可以解决这个问题吗?如果我可以让 pythonzipfile工作,那就太好了,因为我已经有一些单元测试,如果我要切换到运行,我将不得不放弃subprocess.call("unzip")

4

3 回答 3

7

在我的文件上遇到同样的问题并且能够解决它。我不确定它们是如何生成的,就像上面的例子一样。它们最终都有被 Windows 7z 和失败的 python zipfile 忽略的尾随数据。

这是解决问题的代码:

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("Truncating 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  
于 2011-09-17T20:49:50.907 回答
1

你说less在文件上使用它显示了这样那样的。你是这个意思吗?

less my_file

如果是这样,我猜这些是 zip 程序放在文件中的注释。查看我在网上找到的 iSeries PKZIP 用户指南,这似乎是默认行为。

文档zipfile说“此模块当前不处理附加注释的 ZIP 文件。” 也许这就是问题所在?(当然,如果less显示它们,这似乎意味着它们是 前置的,FWIW。)

看来您(或在 iSeries 机器上创建 zipfile 的任何人)可以使用 将其关闭ARCHTEXT(*NONE),或用于ARCHTEXT(*CLEAR)将其从现有 zipfile 中删除。

于 2011-04-05T10:37:12.440 回答
0
# Utilize mmap module to avoid a potential DoS exploit (e.g. by reading the
# whole zip file into memory). A bad zip file example can be found here:
# https://bugs.python.org/issue24621

import mmap
from io import UnsupportedOperation
from zipfile import BadZipfile

# The end of central directory signature
CENTRAL_DIRECTORY_SIGNATURE = b'\x50\x4b\x05\x06'


def repair_central_directory(zipFile):
    if hasattr(zipFile, 'read'):
        # This is a file-like object
        f = zipFile
        try:
            fileno = f.fileno()
        except UnsupportedOperation:
            # This is an io.BytesIO instance which lacks a backing file.
            fileno = None
    else:
        # Otherwise, open the file with binary mode
        f = open(zipFile, 'rb+')
        fileno = f.fileno()
    if fileno is None:
        # Without a fileno, we can only read and search the whole string
        # for the end of central directory signature.
        f.seek(0)
        pos = f.read().find(CENTRAL_DIRECTORY_SIGNATURE)
    else:
        # Instead of reading the entire file into memory, memory-mapped the
        # file, then search it for the end of central directory signature.
        # Reference: https://stackoverflow.com/a/21844624/2293304
        mm = mmap.mmap(fileno, 0)
        pos = mm.find(CENTRAL_DIRECTORY_SIGNATURE)
        mm.close()
    if pos > -1:
        # size of 'ZIP end of central directory record'
        f.truncate(pos + 22)
        f.seek(0)
        return f
    else:
        # Raise an error to make it fail fast
        raise BadZipfile('File is not a zip file')
于 2018-12-10T15:34:34.980 回答