2013-12-16 12 views
6

मेरे पास फ़ाइल के पहले संगत 2/3s हैं जो zlib के डिफ्लेट() फ़ंक्शन से संपीड़ित थे। अंतिम 1/3 ट्रांसमिशन में खो गया था। मूल असंपीड़ित फ़ाइल 600 केबी थी।आंशिक zlib फ़ाइल को कैसे बढ़ाया जाए

Deflate 2KB का हिस्सा आकार में मूल फ़ाइल काटना और फ़ाइल के अंत तक Z_NO_FLUSH गुजर जब Z_FINISH पारित किया गया था, जबकि ट्रांसमीटर द्वारा कई बार बुलाया गया था। परिणामस्वरूप पूर्ण संपीड़ित फ़ाइल प्रसारित की गई थी, लेकिन वर्णित रूप से आंशिक रूप से खो गई थी।

क्या मूल फ़ाइल का हिस्सा पुनर्प्राप्त करना संभव है? यदि हां, तो इस पर कोई सुझाव कैसे?

मैं ZLIB के सादे सी कार्यान्वयन और/या पाइथन 2.7 ZLIB के कार्यान्वयन दोनों का उपयोग कर रहा हूं।

उत्तर

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 routines के साथ tinkering की जरूरत है। http://www.zlib.net/zlib_how.html में हम एक उदाहरण कार्यक्रम zpipe.c मिल जाए, और पंक्ति का वर्णन करके अपने कतार में:

हिस्सा बस के लिए डेटा खिला और zlib दिनचर्या से डेटा खींचने के लिए बफर आकार है। बड़े बफर आकार अधिक कुशल होंगे, खासकर फुलाए जाने के लिए()। यदि स्मृति उपलब्ध है, 128K या 256K बाइट्स के क्रम पर बफर आकार का उपयोग किया जाना चाहिए।

#define CHUNK 16384 
... 

यहाँ मेरी सुझाव है: आप बफर बहुत छोटे सेट - यदि समर्थित है, शायद एक भी बाइट के लिए। इस तरह, आप अपरिहार्य Z_BUF_ERROR तक जितना संभव हो उतना डिकंप्रेस करेंगे। उस बिंदु पर, आमतौर पर एकत्रित डेटा को छोड़ देता है (समयपूर्व deflate_end कॉलों को देखें जो आपकी पीठ के पीछे "साफ करें") लेकिन आपके मामले में आप बस एक फ़ाइल में स्ट्रीम कर सकते हैं और जब आप पाते हैं कि आप नहीं जा सकते हैं तो इसे बंद कर सकते हैं।

उत्पादन के अंतिम कुछ बाइट्स पिटाई हो सकता है अगर गलत "अंतिम" प्रतीक डीकोड कर ली, या zlib बल्कि एक आंशिक प्रतीक outputting से समय से पहले ही निरस्त कर सकते हैं। लेकिन आप जानते हैं कि आपका डेटा अधूरा होगा, इसलिए यह कोई समस्या नहीं होनी चाहिए।

2

अद्यतन: @Mark Adler pointed out के रूप में; आंशिक सामग्री zlib.decompressobj का उपयोग कर decompressed जा सकता है:

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

जहां part नीचे परिभाषित किया गया है।

--- पुरानी टिप्पणी इस प्रकार है:

डिफ़ॉल्ट zlib तक अजगर में आंशिक सामग्री को संभालने के नहीं है।

यह काम करता है:

>>> 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 
संबंधित मुद्दे