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?

War es hilfreich?

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 bis windowBits 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 eine Z_DATA_ERROR). Wenn ein gzip Strom decodiert wird, ist strm->adler      ein crc32 anstelle eines adler32.

Andere Tipps

Python

zlib Bibliothek unterstützt :

Das Python zlib Modul werden diese auch unterstützen.

Auswahl windowBits

Aber zlib können alle diese Formate dekomprimieren:

  • (De-) komprimieren deflate Format, Verwendung wbits = -zlib.MAX_WBITS
  • (De-) komprimieren zlib Format, Verwendung wbits = zlib.MAX_WBITS
  • (De-) komprimieren gzip Format, Verwendung wbits = 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()

Die Struktur der zlib und gzip ist anders. zlib verwendet RFC 1950 und gzip verwendet RFC 1952 , so haben unterschiedliche Header, aber der Rest hat die gleiche Struktur und folgt dem RFC 1951 .

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top