ZIP文件各部分的总和与其大小不符

4 投票
1 回答
894 浏览
提问于 2025-05-16 19:20

简而言之 - 我现在在做一个项目,目的是提供关于一个压缩文件里条目的信息,并且要说明这些条目的大小是从哪里来的。下面的例子虽然和我的实际问题(有成千上万条目)不完全一样,但能突出我遇到的实际问题。我的问题是,压缩文件里有一部分大小是无法解释的(我猜是用于压缩的额外开销)。我压缩文件里所有条目的总大小加上它们之间的预期空隙,结果还小于压缩文件的实际大小。我该如何检查这个压缩文件,以便了解这些隐藏的开销呢?

目前的情况:

我有一个文件夹,里面有三个文件:

  1. doc.pdf
  2. cat.jpg
  3. model.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      |
|---------------------|-----------------|---------------|

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

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字节)。

但事实并非如此。所以显然,压缩需要头部信息和关于如何压缩(以及如何解压缩)的信息。但我遇到的问题是如何定义这个信息或获取更多相关信息。

我可以简单地用84469减去84102,得到~神秘的压缩开销~ = 367字节。但这似乎不太理想,因为这个数字显然不是神秘的。有没有办法检查底层的zip数据,看看这些占用的空间是怎么回事?

相关问题:

  • 暂无相关问题
暂无标签

1 个回答

0

一个空的zip文件大小是22字节,里面只包含了中央目录记录的结束部分。

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文件不为空,那么每个文件都会有一个中央目录文件的头部(至少46字节),还有一个本地文件头(至少30字节)。

这些头部的实际长度是可变的,因为这些给出的长度不包括文件名的空间,而文件名也是头部的一部分。

撰写回答