2013-12-16 9 views
6

私はzlibのdeflate()関数で圧縮されたファイルの最初の連続した2/3を持っています。最後の1/3は送信時に失われました。元の圧縮されていないファイルは600KBでした。部分的なzlibファイルを展開する方法

Deflateは元のファイルを2KBのチャンクサイズにチョッピングし、Z_FINISHが渡されたときにファイルの終わりまでZ_NO_FLUSHを渡しながら、トランスミッタによって複数回呼び出されました。結果の完全圧縮ファイルは送信されましたが、説明どおりに部分的に失われました。

元のファイルの一部を復元することはできますか?もしそうなら、どのように提案する?

私は、ZLIBのプレーンC実装、および/またはZLIBのPython 2.7実装の両方を使用しています。

答えて

10

私のpythonを知らないけど、私はこの仕事を得るために管理:

#!/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

次のは理論的にはdobubleと思われますが、低レベルのzlibルーチンを使って作業する必要があります。 http://www.zlib.net/zlib_how.htmlでは、プログラム例zpipe.cを見つけ、回線記述によって、その行に:

チャンクは単にデータを供給し、ZLIBルーチンからデータを引っ張るためのバッファサイズです。バッファサイズを大きくすると、特にinflate()の方が効率的です。メモリが使用可能な場合は、128Kまたは256Kバイトのオーダーのバッファサイズを使用する必要があります。

#define CHUNK 16384 
... 

は、ここに私の提案です:あなたは非常に小さいバッファを設定する - サポートされている場合、多分単一バイトに。そうすれば、不可避のZ_BUF_ERRORまで可能な限り解凍します。その時点で、通常、収集されたデータは破棄されます(あなたの背後にある "クリーンアップ"という早期の呼び出しを探します)が、あなたの場合は、ファイルにストリームして、続行できないときに閉じることができます。

間違った「最終」シンボルがデコードされた場合、出力の最後の数バイトにスラッシュが含まれている可能性があります。または、部分シンボルを出力するのではなくzlibが途中で中断することがあります。しかし、あなたはあなたのデータが不完全であることを知っていますとにかく、それは問題ではないはずです。

2

更新:@Mark Adler pointed out;部分的なコンテンツはzlib.decompressobjを使用して解凍することができる。partは以下に定義される

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

---古いコメントは次のとおりです。デフォルト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 
関連する問題