14

我想连接两个或多个 gzip 流而不重新压缩它们。

我的意思是我将 A 压缩为 A.gz,将 B 压缩为 B.gz,我想使用 C 或 C++ 将它们压缩为单个 gzip (A+B).gz 而无需再次压缩。

几个注意事项:

  • 即使你可以只连接两个文件,而 gunzip 知道如何处理它们,大多数程序也无法处理两个块。
  • 我曾经见过一个代码示例,它仅通过解压缩文件然后操作原始文件来执行此操作,这比正常的重新压缩要快得多,但仍然需要 O(n) CPU 操作。
  • 不幸的是,我找不到我曾经找到过的这个例子(仅使用解压缩进行连接),如果有人能指出它,我会很高兴。

注意:它不是重复的,因为建议的解决方案不适合我的需要。

清除编辑

我想根据请求连接几个压缩的 HTML pices 并将它们作为一页发送到浏览器:“Accept-Encoding:gzip”,响应为“Content-Encoding:gzip”

如果将流连接为简单的cat a.gz b.gz >ab.gz,Gecko (firefox) 和 KHTML Web 引擎只得到第一部分 (a);IE6 不显示任何内容,Google Chrome 将第一部分 (a) 正确显示,第二部分 (b) 显示为垃圾(根本不解压缩)。

只有 Opera 能很好地处理这个问题。

因此,我需要创建一个包含多个块的 gzip 流并在不重新压缩的情况下发送它们。

更新:我在 zlib 的示例中找到了gzjoin.c,它只使用解压缩。问题是解压还是比较慢,简单memcpy

它仍然比最快的 gzip 压缩快 4 倍。但这还不够。

我需要的是找到我需要与 gzip 文件一起保存的数据,以便不运行解压缩程序,以及如何在压缩过程中找到这些数据。

4

4 回答 4

14

查看RFC1951RFC1952

该格式只是一组成员,每个成员由三部分组成,标题,数据和尾部。数据部分本身就是一组块,每个块都有一个标题和数据部分。

要模拟 gzip 压缩两个(或多个文件)串联结果的效果,您只需正确调整标头(例如最后一个块标志)和尾部并复制数据部分。

有一个问题,预告片有一个未压缩数据的 CRC32,当你知道零件的 CRC 时,我不确定这个是否容易计算。

编辑:您发现的 gzjoin.c 文件中的注释暗示,虽然可以在不解压缩数据的情况下计算 CRC32,但还有其他需要解压缩的东西。

于 2009-07-17T13:57:57.230 回答
6

gzip 手册说可以在您尝试时连接两个 gzip 文件。

http://www.gnu.org/software/gzip/manual/gzip.html#Advanced-usage

所以看起来其他工具可能被破坏了。如本错误报告中所示。 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=97263

除了向每个浏览器制造商提交错误报告并希望他们遵守之外,也许您的程序可以缓存所需数据的最常见连接。

正如其他人所提到的,您也许可以进行手术: http ://www.gzip.org/zlib/rfc-gzip.html

这需要最终未压缩文件的 CRC-32。通过添加各个子文件的长度,可以很容易地计算出未压缩文件所需的大小。

在最后一个链接的底部,有用于计算名为 update_crc 的运行 crc-32 的代码。

每次运行进程时计算未压缩文件的 crc,可能比 gzip 算法本身便宜。

于 2009-07-28T18:01:08.373 回答
2

单个文件的原始压缩似乎是由您完成的。看起来所需的结果(几部分的连接)小到可以在一页中发送到 Web 浏览器。在这种情况下,您的效率问题似乎是没有根据的。

请注意,(1)gzjoin.c 方法很可能是您可以解决问题的最佳答案,如所述(2)它是由 gzip 发起者之一执行的复杂显微外科手术,可能没有经过广泛的研究压力测试。

请考虑一种无聊且可理解的可靠方法:存储未压缩的原始片段,然后选择所需的片段,并将它们连接并压缩。请注意,压缩比可能比将小压缩块粘合在一起获得的压缩比更好。

于 2009-07-26T04:35:18.147 回答
1

如果tar他们不是不可能的(因为链接的cat解决方案对您不可行):

tar cf A_B.gz.tar A.gz B.gz

然后,让他们回来:

tar xf A_B.gz.tar
于 2009-07-17T13:41:06.767 回答