كيف يمكنني إلغاء ضغط دفق Gzip مع زليب؟
سؤال
ملفات تنسيق gzip (تم إنشاؤها مع gzip
البرنامج، على سبيل المثال) استخدم خوارزم ضغط "الانفديل"، وهو نفس خوارزم الضغط مثل ما zlib. الاستخدامات. ومع ذلك، عند استخدام ZLIB لتضخير ملف مضغوط Gzip، تقوم المكتبة بإرجاع Z_DATA_ERROR
.
كيف يمكنني استخدام ZLIB لإلغاء ضغط ملف Gzip؟
المحلول
لإلغاء ضغط ملف تنسيق Gzip مع ZLIB، اتصل inflateInit2
مع ال windowBits
المعلمة كما 16+MAX_WBITS
, ، مثله:
inflateInit2(&stream, 16+MAX_WBITS);
إذا لم تقم بذلك، فسوف يشتكي ZLIB من تنسيق دفق سيء. بشكل افتراضي، يقوم ZLIB بإنشاء تدفقات ذات رأس ZLIB، وعلى تضخيم لا يتعرف على رأس Gzip المختلف إلا إذا أخبرته بذلك. على الرغم من أن هذا موثق يبدأ في الإصدار 1.2.1 من zlib.h
ملف الرأس، إنه ليس في دليل ZLIB. وبعد من ملف الرأس:
windowBits
يمكن أن يكون أيضا أكبر من 15 للحصول على فك تشفير gzip الاختياري. إضافة 32 إلىwindowBits
لتمكين فك تشفير ZLIB و GZIP مع كشف الرأس التلقائي، أو أضف 16 لفك تشفير فقط تنسيق Gzip (سوف يعيد تنسيق ZLIBZ_DATA_ERROR
). إذا تم فك تشفير دفق gzip،strm->adler
هو CRC32 بدلا من Adler32.
نصائح أخرى
بيثون
بيثون zlib
الوحدة سوف تدعم هذه كذلك.
اختيار windowbits.
ولكن zlib
يمكن إلغاء ضغط كل تلك التنسيقات:
- إلى (de-) ضغط
deflate
التنسيق، واستخدامwbits = -zlib.MAX_WBITS
- إلى (de-) ضغط
zlib
التنسيق، واستخدامwbits = zlib.MAX_WBITS
- إلى (de-) ضغط
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
الوحدة النمطية مباشرة. لكن يرجى تذكر ذلك تحت غطاء محرك السيارة, gzip
الاستخدامات zlib
.
fh = gzip.open('abc.gz', 'rb')
cdata = fh.read()
fh.close()
node.js.
const { gunzip } = require('zlib');
const decompressGzip = compressedData =>
new Promise((resolve, reject) => {
gunzip(compressedData, (error, decompressedData) => {
if (error) return reject(error);
return resolve(decompressedData);
});
});
module.exports = { decompressGzip };
قمت بتثبيت zlib
باستخدام الغزل
yarn add zlib