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

时间:2017-04-29 19:28:58

标签: python archive

TL; DR - 实际问题是我正在处理一些提供存档文件中条目信息的内容,并指定存档中大小的“位置”。下面的例子与我真正的问题(它有数十万个条目)完全不同,但突出了我遇到的实际问题。我的问题是我的存档中有一个非常重要的大小,但是没有计算(实际上用于压缩的开销是我的猜测)。我的存档部分的总和(所有条目的总压缩大小+它们之间的预期间隙)小于存档的实际大小。如何以一种能够深入了解这种隐藏开销的方式检查存档?

我在哪里:

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

  1. doc.pdf
  2. cat.jpg
  3. model.stl
  4. 使用免费软件程序我将这些转储到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 :(得分:0)

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

实际标题的可变长度,因为给定的长度不包含作为标题一部分的文件名的空间。