如何读取 python 中用 pkzip 编写的 zip 文件?

How to read a zip file written with pkzip in python?

我正在尝试读取 python 中使用 pkzip 编写的 zip 文件:

import zipfile
fname = "myfile.zip"
unzipped = zipfile.ZipFile(fname, "r")

但是得到这个错误:

    unzipped = zipfile.ZipFile(fname, "r")
  File "/home/username/anaconda3/envs/c1/lib/python3.7/zipfile.py", line 1222, in __init__
    self._RealGetContents()
  File "/home/username/anaconda3/envs/c1/lib/python3.7/zipfile.py", line 1285, in _RealGetContents
    endrec = _EndRecData(fp)
  File "/home/username/anaconda3/envs/c1/lib/python3.7/zipfile.py", line 282, in _EndRecData
    return _EndRecData64(fpin, -sizeEndCentDir, endrec)
  File "/home/username/anaconda3/envs/c1/lib/python3.7/zipfile.py", line 228, in _EndRecData64
    raise BadZipFile("zipfiles that span multiple disks are not supported")
zipfile.BadZipFile: zipfiles that span multiple disks are not supported

据我所知,这个文件没有跨越多个磁盘。我这样说是因为:

  1. 检查 against the solution in this Whosebug answer,我的 zipfile 版本已适当修补。

  2. 它可以很好地解压缩:

    $ unzip myfile.zip
    

    在 linux 命令行上。

所以,它似乎并不是一个坏的 zip 文件。通过使用原始文件访问打开它来读取前几个字节,有一个暗示 header PKzip 可能正在以一种有趣的方式格式化这个文件:

  b'PK\x03

查看 zipfile 的 python 库文档,有一个 PKZIP 应用说明:

The ZIP file format is a common archive and compression standard. This module provides tools to create, read, write, append, and list a ZIP file. Any advanced use of this module will require an understanding of the format, as defined in PKZIP Application Note.

其中links here。这非常彻底,但我没有看到关于如何将哪些选项添加到对 zipfile 的调用中以便正确解析文件的具体说明。

PKZIP 的使用相当广泛,因此我很惊讶找不到更常见的示例或本机支持。在 python 中打开一个 pkzipped 文件并抛出此 multiple-disk 错误需要哪些选项?

您发布的 link 与此

相比发生了变化 zipfile
if diskno != 0 or disks != 1:
    raise BadZipFile("zipfiles that span multiple disks are not supported")

至此

if diskno != 0 or disks > 1:
    raise BadZipFile("zipfiles that span multiple disks are not supported")

如果您仍然收到错误“不支持跨多个磁盘的压缩文件”,这意味着 diskno != 0disks > 1

你需要进一步了解myfile.zip的内部结构。

尝试 运行 zipdetails 并检查最后一节的输出。下面是单个磁盘存档的样子

# zipdetails  fred.zip 
...
3CF31 END CENTRAL HEADER    06054B50
3CF35 Number of this disk   0000
3CF37 Central Dir Disk no   0000
3CF39 Entries in this disk  0009
3CF3B Total Entries         0009
3CF3D Size of Central Dir   00000317
3CF41 Offset to Central Dir 0003CC1A
3CF45 Comment Length        0000
Done