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