Wie kann ich einen gzip-Stream mit zlib dekomprimieren?
108
Dateien im Gzip-Format ( gzipzum Beispiel mit dem Programm erstellt ) verwenden den Komprimierungsalgorithmus "deflate", der der gleiche Komprimierungsalgorithmus ist wie der von zlib . Wenn Sie jedoch zlib zum Aufblasen einer gzip-komprimierten Datei verwenden, gibt die Bibliothek a zurück Z_DATA_ERROR.
Wie kann ich mit zlib eine gzip-Datei dekomprimieren?
Um eine Datei im GZIP-Format mit zlib zu dekomprimieren, rufen Sie inflateInit2den folgenden windowBitsParameter auf 16+MAX_WBITS:
inflateInit2(&stream, 16+MAX_WBITS);
Wenn Sie dies nicht tun, beschwert sich zlib über ein schlechtes Stream-Format. Standardmäßig erstellt zlib Streams mit einem zlib-Header und erkennt beim Aufblasen die verschiedenen gzip-Header nur, wenn Sie dies mitteilen. Obwohl dies ab Version 1.2.1 der zlib.hHeader-Datei dokumentiert ist , ist es nicht im zlib-Handbuch enthalten . Aus der Header-Datei:
windowBitskann für die optionale gzip-Dekodierung auch größer als 15 sein. Fügen Sie 32 hinzu, windowBitsum die Zlib- und GZIP-Dekodierung mit automatischer Header-Erkennung zu aktivieren, oder fügen Sie 16 hinzu, um nur das GZIP-Format zu dekodieren (das ZLIB-Format gibt a zurück Z_DATA_ERROR). Wenn ein gzip-Stream dekodiert wird, strm->adlerist ein crc32 anstelle eines adler32.
Danke, das war sehr frustrierend, bis ich diesen Beitrag gefunden habe.
Alex
Wow, das ist die Frage von 2009. Danke @ Greg Hewgill
YuAn Shaolin Maculelê Lai
Vielleicht können Sie einige Richtlinien für die iterative Dekomprimierung von gzip stream bereitstellen. Bei der One-Shot-GZIP-Dekomprimierung, bei der Ihr Ausgabestream und Ihre Größe fest und ausreichend sein sollten, um die gesamte dekomprimierte Ausgabe zu speichern. Dieser Wert hängt von der Wirksamkeit der gzip-Dekompression ab, die je nach Datenentropie variieren kann. Gibt es eine Möglichkeit, dem Ausgabepuffer bei Bedarf dynamisch mehr Speicherplatz zuzuweisen? Danke
Warum steht dieses Stück Gold nicht in den Dokumenten zu diesem Format?
Ramon Moraes
Bitte zögern Sie nicht, eine Pull-Anfrage / einen Patch gegen cpython mit einer dieser Antworten zu senden.
dnozay
Gute Antwort für Zeichenfolgen. Haben Sie eine Idee, wie Sie dies für einen Stream tun können, ohne die gesamte Datei in den Speicher einzulesen?
Josh J
Danke dir. Ich kann mein Dekomprimierungsproblem in meinem Quellcode mit Ihrer Antwort lösen.
Bethlee
Unglaublich, das ist ein Goldnugget. Aber ich kann nicht anders, als zu glauben, dass dies gleichbedeutend mit 'magischen Zahlen' ist. Wo in der Dokumentation wird dies erwähnt? Ich habe nachgesehen, muss aber wirklich nicht genau genug nachgesehen haben. Auch die Notation, der ich nicht vollständig folge. Was macht der | meine, ist das optional? und warum ist deflate negativ .. ist MAX_WBITS eine Konstante .. 🙁
m1nkeh
3
Die Struktur von zlib und gzip ist unterschiedlich. zlib verwendet RFC 1950 und gzip verwendet RFC 1952 , hat also unterschiedliche Header, aber der Rest hat die gleiche Struktur und folgt dem RFC 1951 .
zlib.decompress(data, 15 + 32)
Python
zlib
Bibliothek unterstützt :zlib
komprimiertes Format)deflate
komprimiertes Format)gzip
komprimiertes Format)Das Python-
zlib
Modul unterstützt diese ebenfalls.Fensterbits auswählen
Aber
zlib
können alle diese Formate dekomprimieren:deflate
Verwenden Sie zum (De-) Komprimieren des Formatswbits = -zlib.MAX_WBITS
zlib
Verwenden Sie zum (De-) Komprimieren des Formatswbits = zlib.MAX_WBITS
gzip
Verwenden Sie zum (De-) Komprimieren des Formatswbits = zlib.MAX_WBITS | 16
Siehe Dokumentation unter http://www.zlib.net/manual.html#Advanced (Abschnitt
inflateInit2
)Beispiele
Testdaten:
offensichtlicher Test für
zlib
:Test für
deflate
:Test für
gzip
:Die Daten sind auch kompatibel mit
gzip
Modul:automatische Header-Erkennung (zlib oder gzip)
Durch Hinzufügen
32
zuwindowBits
wird die Headererkennung ausgelöstVerwendung
gzip
anstelleFür
gzip
Daten mit gzip-Header können Sie dasgzip
Modul direkt verwenden. aber denken Sie bitte daran , dass unter der Haube ,gzip
Anwendungenzlib
.quelle
Die Struktur von zlib und gzip ist unterschiedlich. zlib verwendet RFC 1950 und gzip verwendet RFC 1952 , hat also unterschiedliche Header, aber der Rest hat die gleiche Struktur und folgt dem RFC 1951 .
quelle