如何连接两个或多个gzip文件/流

时间:2009-07-17 13:29:38

标签: c++ gzip concatenation

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

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

几点说明:

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

注意:它不与this重复,因为提议的解决方案不符合我的需要。

清除修改

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

如果流简化为cat a.gz b.gz >ab.gz,Gecko(firefox)和KHTML Web引擎只获得第一部分(a); IE6没有显示任何内容,谷歌浏览器正确显示第一部分(a),第二部分(b)显示为垃圾(根本不解压缩)。

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

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

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

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

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

4 个答案:

答案 0 :(得分:12)

查看RFC1951RFC1952

格式只是一个成员套件,每个成员由三部分组成,标题,数据和预告片。数据部分本身就是一组块,每个块都有一个头和数据部分。

要模拟gzipping两个(或更多文件)串联结果的效果,您只需调整标题(例如最后一个chunk标志)并正确拖放并复制数据部分。

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

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

答案 1 :(得分: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算法本身便宜。

答案 2 :(得分:2)

如果问tar不是不可能的(因为链接的cat solution对您不可行):

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

然后,让他们回来:

tar xf A_B.gz.tar

答案 3 :(得分:2)

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

请注意,(1)gzjoin.c方法极有可能成为您提出的问题的最佳答案(2)由一个gzip发起者执行的复杂显微手术并且可能没有受到广泛的压力测试。

请考虑一种无聊可理解的可靠方法:存储原始碎片UN压缩,然后选择所需的碎片,并连接并压缩它们。请注意,压缩比可能优于通过将小的压缩件粘合在一起而获得的压缩比。