【问题标题】:What's the most that GZIP or DEFLATE can increase a file size?GZIP 或 DEFLATE 最多可以增加文件大小是多少?
【发布时间】:2014-06-27 14:14:42
【问题描述】:

众所周知,GZIP 或 DEFLATE(或任何压缩机制)有时会增加文件大小。文件可以增加的最大值(百分比或常数)吗?这是什么?

如果一个文件是 X 字节,我要对其进行 gzip 压缩,并且我需要提前预算文件空间 - 最坏的情况是什么?

更新:有两个开销:GZIP 添加了一个标头,通常为 18 个字节,但基本上是任意长的。放气呢?这可以通过乘法因子扩展内容,我不知道。有人知道是什么吗?

【问题讨论】:

  • 我猜这会将每个字节编码为文字。大概是2倍左右。您可以在压缩流前加上一个 bool 前缀,指示它是否实际经过 gzip 压缩。这允许您将最大空间限制为一个额外的字节。
  • 关于 18 个额外字节:Mark 在此处解释 (stackoverflow.com/a/38148423/43615)。 10 个字节是最短的 gzip 标头(无文件名),8 个字节是校验和的常量尾部以及原始文件长度的低 4 个字节。

标签: compression gzip deflate information-theory libz


【解决方案1】:

gzip 将添加 至少 18 个字节的标题和尾部。标头还可以包含一个路径名,它将添加那么多字节加上一个尾随零。

gzip 中的 deflate 实现可以选择每个块存储 16383 个字节,开销为 5 个字节。如果替代方案需要更多字节,它将始终选择这样做。所以 n 个输入字节的最大压缩字节数是:

【讨论】:

  • 使用你的公式,我经常有 deflate() 在已经压缩的数据(例如视频)上返回avail_out==0。那不应该发生,对吧?调用前avail_in为10485760,avail_out为10488965,即多了3205。使用 zlib v1.2.5(OSX 10.10.5 上的默认值),压缩级别 9,策略 0,wbits -15。
  • 没关系,我想通了:如果输出是马克公式中给出的确切最大值,那么avail_out==0 将最终为零,但这仍然意味着它是成功的并且无需环回并提供另一个缓冲区。然而,为了安全地告诉这个状态,向输出缓冲区添加一个字节是明智的,这样在生成最大输出大小时,deflate 仍然会在缓冲区中留下一个字节——这样,检查avail_out== 0 永远不会命中,如果会,这清楚地表明出了问题。
【解决方案2】:

压缩文件总是有一个标头指示如何解压缩。

当压缩无法压缩的文件时,该标头的大小表示最坏情况下的开销(因为数据没有顺序/模式;它是随机的)。

标题因特定算法而异,并且可能包含可变长度信息,例如存档中的文件列表。

GZip 至少有 18 字节的开销(页眉 + 页脚中的 CRC-32),并且可以选择包含存档中的文件列表。

http://en.wikipedia.org/wiki/Gzip#File_format

请注意,在特殊情况下,自定义压缩算法可以减少或消除标头开销。例如,我使用压缩和解压缩软件已知的自定义压缩字典来压缩短文本,因此不需要标题。这是一个相当罕见的用例,在大多数情况下可能没有用(考虑到存储和带宽相对便宜)。

【讨论】:

  • GZIP 中的块也可以更长 - 因此,除了 +18 之外,还有一些比例因子。不过不确定是什么。
  • 这可能是维基百科文章中提到的可选标题之一。并非每个 GZIP 实现都必须包含它(除非文章有误)。
猜你喜欢
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 2011-01-26
  • 2021-04-27
相关资源
最近更新 更多