2009-07-17 115 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算法本身便宜。