2013-12-16 28 views
6

我有用zlib的deflate()函數壓縮的文件的第一個連續的2/3rds。傳輸中最後1/3丟失。原始的未壓縮文件是600KB。如何給部分zlib文件充氣

發送器將deflate多次調用,同時將原始文件切分爲2KB的塊大小,並在Z_FINISH通過時將Z_NO_FLUSH傳遞給文件結尾。由此產生的完整壓縮文件被傳輸,但如上所述部分丟失。

是否有可能恢復部分原始文件?如果是這樣,有什麼建議如何?

我使用ZLIB的純C實現和/或ZLIB的Python 2.7實現。

回答

10

雖然我不知道蟒蛇,我設法得到這個工作:

#!/usr/bin/python 
import sys 
import zlib 
f = open(sys.argv[1], "rb") 
g = open(sys.argv[2], "wb") 
z = zlib.decompressobj() 
while True: 
    buf = z.unconsumed_tail 
    if buf == "": 
     buf = f.read(8192) 
     if buf == "": 
      break 
    got = z.decompress(buf) 
    if got == "": 
     break 
    g.write(got) 

這應該提取所有這可從部分zlib的文件。

+0

謝謝,是使用decompressobj ()工作。我只是簡單地使用zlib.decompress(),它給出了一個錯誤。使用dc_obj = zlib.decompressobj()和decomp_data_str = dc_obj.decompress(orig_data_str)解決了這個問題。 – JohnSantaFe

0

以下似乎在理論上是可行的,但需要修補低級zlib例程來工作。在http://www.zlib.net/zlib_how.html我們找到一個例子程序zpipe.c,並在其逐行描述:

CHUNK僅僅是用於饋送數據到和從所述zlib的例程拉動數據緩衝區的大小。更大的緩衝區大小會更有效,特別是對於inflate()。如果內存可用,則應使用大小爲128K或256K的緩衝區大小。

#define CHUNK 16384 
... 

這裏是我的建議:你設置緩衝區很小 - 如果支持的話,甚至到一個字節。這樣,你將盡可能地解壓縮到不可避免的Z_BUF_ERROR。此時,通常會丟棄收集的數據(查找過早的deflate_end調用,在您的背後「清理」),但在您的情況下,您可以簡單地將流傳輸到文件並在發現無法繼續時關閉它。

如果錯誤的「最終」符號被解碼,或者zlib可能提前中止,輸出的最後幾個字節可能包含thrash,而不是輸出部分符號。但是你知道你的數據將會不完整,所以這應該不成問題。

2

更新:作爲@Mark Adler pointed out;部分的內容可以使用zlib.decompressobj被解壓縮:

>>> decompressor = zlib.decompressobj() 
>>> decompressor.decompress(part) 
"let's compress some t" 

其中part定義如下。

---舊的評論如下:

默認情況下zlib不會在Python處理部分內容。

這工作:

>>> compressed = "let's compress some text".encode('zip') 
>>> compressed 
'x\x9c\xcbI-Q/VH\xce\xcf-(J-.V(\xce\xcfMU(I\xad(\x01\x00pX\t%' 
>>> compressed.decode('zip') 
"let's compress some text" 

如果我們將它截斷它不工作:

>>> part = compressed[:3*len(compressed)/4] 
>>> part.decode('zip') 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
    File ".../lib/python2.7/encodings/zlib_codec.py", lin 
e 43, in zlib_decode 
    output = zlib.decompress(input) 
error: Error -5 while decompressing data: incomplete or truncated stream 

同樣,如果我們使用zlib明確:

>>> import zlib 
>>> zlib.decompress(compressed) 
"let's compress some text" 
>>> zlib.decompress(part) 
Traceback (most recent call last): 
    File "<input>", line 1, in <module> 
error: Error -5 while decompressing data: incomplete or truncated stream