Wie kann ich einen gzip-Stream mit zlib dekomprimieren?
Frage
gzip-Format-Dateien (mit dem gzip
Programm erstellt, zum Beispiel) verwenden, um den „deflate“ Kompressionsalgorithmus, der der gleiche Kompressionsalgorithmus ist wie das, was zlib verwendet. Wenn jedoch zlib mit einer gzip komprimierte Datei aufzublasen, die Bibliothek gibt eine Z_DATA_ERROR
.
Wie kann ich zlib eine gzip-Datei entpacken?
Lösung
Um eine gzip-Format-Datei mit zlib dekomprimieren, rufen inflateInit2
mit dem windowBits
Parameter wie 16+MAX_WBITS
, wie folgt aus:
inflateInit2(&stream, 16+MAX_WBITS);
Wenn Sie dies nicht tun, zlib wird über ein schlechtes Stream-Format beschweren. Standardmäßig erstellt zlib-Streams mit einem zlib-Header und auf aufblasen nicht die verschiedenen gzip-Header erkennen, wenn Sie es so sagen. Obwohl dies in Start-Version 1.2.1 der zlib.h
Header-Datei dokumentiert wird, ist es nicht in dem zlib Handbuch . Aus der Header-Datei:
windowBits
kann auch größer als 15 für optionale gzip-Decodierung. Hinzufügen 32 biswindowBits
zlib und gzip Decodierung mit automatischen Header zu ermöglichen Detektion oder 16 fügt nur das gzip-Format (das Format wird zlib zu dekodieren Rückkehr eineZ_DATA_ERROR
). Wenn ein gzip Strom decodiert wird, iststrm->adler
ein crc32 anstelle eines adler32.
Andere Tipps
Python
- RFC 1950 (
zlib
komprimiertes Format) - RFC 1951 (
deflate
komprimiertes Format) - RFC 1952 (
gzip
komprimiertes Format)
Das Python zlib
Modul werden diese auch unterstützen.
Auswahl windowBits
Aber zlib
können alle diese Formate dekomprimieren:
- (De-) komprimieren
deflate
Format, Verwendungwbits = -zlib.MAX_WBITS
- (De-) komprimieren
zlib
Format, Verwendungwbits = zlib.MAX_WBITS
- (De-) komprimieren
gzip
Format, Verwendungwbits = zlib.MAX_WBITS | 16
Siehe Dokumentation in http://www.zlib.net/manual.html#Advanced (Abschnitt inflateInit2
)
Beispiele
Testdaten:
>>> 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()
>>>
offensichtlich Test für zlib
:
>>> zlib.decompress(zlib_data)
'test'
Test für 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'
Test für 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'
die Daten sind auch kompatibel mit gzip
Modul:
>>> import gzip
>>> import StringIO
>>> fio = StringIO.StringIO(gzip_data)
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
'test'
>>> f.close()
automatische Kopferkennung (zlib oder gzip)
32
Zugabe wird windowBits
Kopferkennung auslösen
>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32)
'test'
>>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32)
'test'
mit gzip
statt
Für gzip
Daten mit gzip-Header Sie gzip
Modul direkt verwenden können; aber denken Sie bitte daran, dass unter der Haube , gzip
verwendet 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 };
Sie installieren zlib
Garn mit
yarn add zlib