2009-07-17 109 views
11

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

我的意思是我有一个压缩到A.gz和B到B.gz,我想压缩他们到单个gzip(A + B).gz没有再次压缩,使用C或C++。

几个注意事项:

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

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

Clearification编辑

我想concate几个压缩HTML PICES并将它们发送到浏览器作为一个页面,按照要求:“接受编码:gzip”,与respnse“内容编码: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文件一起保存的数据,以便 不运行解压过程,以及如何在压缩过程中找到这些数据。

+0

你真的想要压缩它们吗,还是将它们连接到同一个文件? – 2009-07-17 13:38:43

+0

我想创建一个gzip压缩文件/流/内存块的两个其他gzip压缩文件/流/内存块没有解压缩他们,连接他们,并再次压缩他们。 – Artyom 2009-07-17 14:32:36

+0

请参阅编辑中的清除。 – Artyom 2009-07-24 08:15:16

回答

11

RFC1951RFC1952

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

为了模拟gzip压缩的两个(或多个文件)的连接结果的影响,你只需要调整头(没有例如最后一块标志)和拖车正确,复制数据部分。

有一个问题,拖车有一个CRC32的未压缩数据,我不知道这个是否容易计算,当你知道部件的CRC。

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

2

如果tar荷兰国际集团他们是不是出了问题(因为链接cat solution是不可行的你):

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

然后,让他们回来:

tar xf A_B.gz.tar 
2

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

请注意:(1)gzjoin.c方法极有可能成为您提到的问题的最佳答案,如上所述(2)由gzip发起者之一执行的复杂的显微外科手术,可能不会已经受到广泛的压力测试。

请考虑一个无聊可理解的可靠方法:存储UNcompressed的原始片断,然后选择所需的片断,并连接并压缩它们。请注意,压缩比可能比通过粘合小压缩片获得的压缩比好。

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算法本身便宜。