मैं zlib के साथ एक gzip स्ट्रीम कैसे हटा सकता हूं?


108

Gzip प्रारूप फाइलें ( gzipउदाहरण के लिए, प्रोग्राम के साथ बनाई गई ) "डिफ्लेट" संपीड़न एल्गोरिदम का उपयोग करती हैं, जो कि zlib का उपयोग करने के समान संपीड़न एल्गोरिथम है । हालाँकि, जब gzip संपीड़ित फ़ाइल को बढ़ाने के लिए zlib का उपयोग किया जाता है, तो लाइब्रेरी a Z_DATA_ERROR

मैं gzip फ़ाइल को डिकम्प्रेस करने के लिए zlib का उपयोग कैसे कर सकता हूं?

जवाबों:


118

Zlib के साथ एक gzip प्रारूप फ़ाइल को विघटित करने के लिए, पैरामीटर के inflateInit2साथ इस तरह से कॉल करें:windowBits16+MAX_WBITS

inflateInit2(&stream, 16+MAX_WBITS);

यदि आप ऐसा नहीं करते हैं, तो zlib एक खराब स्ट्रीम प्रारूप के बारे में शिकायत करेगा। डिफ़ॉल्ट रूप से, zlib एक zlib हेडर के साथ स्ट्रीम बनाता है, और फुलाए जाने पर विभिन्न gzip हेडर को नहीं पहचानता है जब तक कि आप इसे नहीं बताते। हालाँकि यह zlib.hशीर्ष लेख फ़ाइल के संस्करण 1.2.1 में शुरू किया गया है , लेकिन यह zlib मैनुअल में नहीं है । हेडर फ़ाइल से:

windowBitsवैकल्पिक gzip डिकोडिंग के लिए 15 से अधिक हो सकता है। windowBitsZlib और gzip डिकोडिंग को स्वचालित हेडर डिटेक्शन के साथ सक्षम करने के लिए 32 जोड़ें , या केवल gzip प्रारूप को डिकोड करने के लिए 16 जोड़ें (zlib प्रारूप वापस आ जाएगा Z_DATA_ERROR)। यदि एक gzip धारा को डिकोड किया जा रहा है, strm->adlerतो adler32 के बजाय crc32 है।


35
अजगर में:zlib.decompress(data, 15 + 32)
रोमन स्टार्कोव

3
धन्यवाद, जब तक मुझे यह पद नहीं मिला, यह बहुत निराशाजनक था।
एलेक्स

वाह, यह 2009 का सवाल है। धन्यवाद @Greg Hewgill
YuAn Shaolin Maculelê Lai

शायद आप gzip स्ट्रीम के पुनरावृत्ति अपघटन के लिए कुछ दिशानिर्देश प्रदान कर सकते हैं। एक-शॉट गज़िप डीकंप्रेसन में जहां आपके आउटपुट स्ट्रीम और आकार को तय किया जाना चाहिए और पूरे विघटित आउटपुट को संग्रहीत करने के लिए पर्याप्त होना चाहिए। यह मान गज़िप डीकंप्रेसन प्रभावशीलता पर निर्भर करता है जो डेटा एन्ट्रॉपी के अनुसार भिन्न हो सकता है। क्या जरूरत पड़ने पर आउटपुट बफर में गतिशील रूप से अधिक स्थान आवंटित करने का एक तरीका है? धन्यवाद
Zohar81

104

अजगर

zlibपुस्तकालय का समर्थन करता है :

  • RFC 1950 ( zlibसंकुचित प्रारूप)
  • RFC 1951 ( deflateसंकुचित प्रारूप)
  • RFC 1952 ( gzipसंकुचित प्रारूप)

अजगर zlibमॉड्यूल इनका भी समर्थन करेगा।

WindowBits का चयन

लेकिन zlibउन सभी प्रारूपों को डिकम्प्रेस कर सकते हैं:

  • , (डी-) सेक deflateप्रारूप, उपयोगwbits = -zlib.MAX_WBITS
  • , (डी-) सेक zlibप्रारूप, उपयोगwbits = zlib.MAX_WBITS
  • , (डी-) सेक gzipप्रारूप, उपयोगwbits = zlib.MAX_WBITS | 16

Http://www.zlib.net/manual.html#Advanced (अनुभाग inflateInit2) में दस्तावेज़ देखें

उदाहरण

परीक्षण डेटा:

>>> deflate_compress = zlib.compressobj(9, zlib.DEFLATED, -zlib.MAX_WBITS)
>>> zlib_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS)
>>> gzip_compress = zlib.compressobj(9, zlib.DEFLATED, zlib.MAX_WBITS | 16)
>>> 
>>> text = '''test'''
>>> deflate_data = deflate_compress.compress(text) + deflate_compress.flush()
>>> zlib_data = zlib_compress.compress(text) + zlib_compress.flush()
>>> gzip_data = gzip_compress.compress(text) + gzip_compress.flush()
>>> 

के लिए स्पष्ट परीक्षण zlib:

>>> zlib.decompress(zlib_data)
'test'

के लिए परीक्षण deflate:

>>> zlib.decompress(deflate_data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(deflate_data, -zlib.MAX_WBITS)
'test'

के लिए परीक्षण gzip:

>>> zlib.decompress(gzip_data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
zlib.error: Error -3 while decompressing data: incorrect header check
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|16)
'test'

डेटा gzipमॉड्यूल के साथ भी संगत है :

>>> import gzip
>>> import StringIO
>>> fio = StringIO.StringIO(gzip_data)
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
'test'
>>> f.close()

स्वचालित हेडर डिटेक्शन (zlib या gzip)

हेडर डिटेक्शन को ट्रिगर करने के 32लिए जोड़नाwindowBits

>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32)
'test'
>>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32)
'test'

gzipइसके बजाय का उपयोग कर

gzipगज़िप हेडर वाले डेटा के लिए आप gzipसीधे मॉड्यूल का उपयोग कर सकते हैं ; लेकिन कृपया याद रखें कि हुड के तहत , gzipका उपयोग करता है zlib

fh = gzip.open('abc.gz', 'rb')
cdata = fh.read()
fh.close()

3
सोने का यह टुकड़ा इस प्रारूप पर डॉक्स पर क्यों नहीं है?
रेमन मोरास

कृपया इस उत्तर में से किसी एक का उपयोग करके खीरे के खिलाफ एक पुल अनुरोध / पैच भेजने के लिए स्वतंत्र महसूस करें।
3

स्ट्रिंग्स के लिए शानदार जवाब, किसी भी विचार को पूरी फाइल को मेमोरी में पढ़े बिना स्ट्रीम के लिए कैसे करें?
जोश जे

धन्यवाद। मैं अपने जवाब के साथ अपने स्रोत कोड में मेरी डिकम्प्रेस समस्या को हल कर सकता हूं।
बेथली

अविश्वसनीय, यह एक सोने की डली है .. हालांकि मैं मदद नहीं कर सकता, लेकिन ये 'जादुई संख्या' के लिए समान हैं? दस्तावेज़ में यह कहाँ उल्लेख किया गया है? मैंने देखा, लेकिन वास्तव में बहुत कठिन जाँच नहीं की जानी चाहिए .. यह भी, मैं पूरी तरह से पालन नहीं करता है। क्या करता है | मतलब, क्या यह वैकल्पिक है? और नकारात्मक क्यों है .. नकारात्मक है MAX_WBITS एक स्थिर .. n
m1nkeh

3

ज़ालिब और गज़िप की संरचना अलग है। zlib RFC 1950 का उपयोग करता है और gzip RFC 1952 का उपयोग करता है , इसलिए अलग-अलग हेडर हैं, लेकिन बाकी की संरचना समान है और RFC 1951 का अनुसरण करता है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.