python - zipfile 存档的部分总和不等于其文件大小

标签 python archive

TL;DR - 实际问题是,我正在研究提供有关存档文件中条目的信息并指定存档中的大小来自“何处”的东西。下面的示例与我的实际问题(有数十万个条目)完全不同,但突出显示了我遇到的实际问题。我的问题是我的存档中有一个不重要的大小是下落不明的(我猜实际上用于压缩的开销)。我的存档部分的总和(我所有条目的总压缩大小 + 它们之间的预期间隙)小于存档的实际大小。我如何以一种可以深入了解这种隐藏开销的方式检查存档?

我在哪里:

我有一个包含三个文件的目录:

  1. doc.pdf
  2. cat.jpg
  3. 模型.STL

使用免费软件程序,我将它们转储到一个 zip 文件中:demo.zip

使用 python 我可以很容易地检查这些:

info_list= zipfile.ZipFile('demo.zip').infolist()
for i in info_list:
    print i.orig_filename
    print i.compress_size
    print i.header_offset

使用此信息我们可以获得一些信息。

demo.zip的总大小为84469

压缩后的大小:

|---------------------|-----------------|---------------|
|      File           | Compressed Size | Header Offset |
|---------------------|-----------------|---------------|
|         doc.pdf     |       21439     |       0       |
|---------------------|-----------------|---------------|
|         cat.jpg     |       48694     |    21495      |
|---------------------|-----------------|---------------|
|       model.stl     |       13870     |    70232      |
|---------------------|-----------------|---------------|

我知道压缩会导致条目之间有一些空间。 (因此,先前条目大小的总和与每个条目的 header 偏移量之间的差异)。您可以计算这个小的“差距”:

gap = offset - previous_entry_size - previous_entry_offset

我可以将图表更新为:

|---------------------|-----------------|---------------|---------------|
|      File           | Compressed Size | Header Offset |     'Gap'     |
|---------------------|-----------------|---------------|---------------|
|         doc.pdf     |       21439     |       0       |       0       |
|---------------------|-----------------|---------------|---------------|
|         cat.jpg     |       48694     |    21495      |       56      |
|---------------------|-----------------|---------------|---------------|
|       model.stl     |       13870     |    70232      |       43      |
|---------------------|-----------------|---------------|---------------|

很酷。所以现在人们可能期望 demo.zip 的大小等于所有条目的大小及其间隙的总和。 (上例中的 84102)。

但事实并非如此。因此,很明显,压缩需要 header 和有关压缩如何发生(以及如何解压缩)的信息。但是我遇到了如何定义它或访问有关它的更多信息的问题。

我可以只取 84469 - 84102 并说 ~magic zip overhead~ = 367 字节。但这似乎不太理想,因为这个数字显然不是魔术。有没有办法检查占用此空间的底层 zip 数据?

最佳答案

一个空的 zip 文件是 22 bytes , 仅包含中央目录记录的结尾。

In [1]: import zipfile

In [2]: z = zipfile.ZipFile('foo.zip', 'w')

In [3]: z.close()

In [4]: import os

In [5]: os.stat('foo.zip').st_size
Out[5]: 22

如果 zip 文件不为空,则每个文件都有一个中央目录文件 header (至少 46 字节)和本地文件头(至少 30 字节)。

实际的 header 有一个可变长度,因为给定的长度不包括作为 header 一部分的文件名的空间。

关于python - zipfile 存档的部分总和不等于其文件大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43699662/

相关文章:

ios - 无法从命令行生成临时 IPA,但它在 Xcode 中有效

ios - armv7、armv7s 和 arm64 的 ipa 存档构建无法安装到 iOS 5.1.1 设备

python - Tkinter - 如何使用停止按钮停止循环?

python - 如何在 Google Trends 中点击 Load More 按钮并通过 Selenium 和 Python 打印所有标题

python - 模拟 xmlrpc.client 方法 python

python - 在 Python 3.1 上使用 OpenCV 的 ctypes 指针

unix - 如何通过CLI重命名7zip存档中的文件?

python - 根据给定的散点几何量化二维表面的粗糙度

liferay - 对 Liferay 6.2 文档库实现存档/备份

ios - 如何在 Swift 中保存 [[Bool]](对 bool 数组的存档数组进行编码)