Comment puis-je décompresser un flux gzip avec zlib?
108
Les fichiers au format Gzip (créés avec le gzipprogramme, par exemple) utilisent l'algorithme de compression "deflate", qui est le même algorithme de compression que celui utilisé par zlib . Cependant, lorsque vous utilisez zlib pour gonfler un fichier compressé gzip, la bibliothèque renvoie un fichier Z_DATA_ERROR.
Comment puis-je utiliser zlib pour décompresser un fichier gzip?
Pour décompresser un fichier au format gzip avec zlib, appelez inflateInit2avec le windowBitsparamètre as 16+MAX_WBITS, comme ceci:
inflateInit2(&stream, 16+MAX_WBITS);
Si vous ne le faites pas, zlib se plaindra d'un mauvais format de flux. Par défaut, zlib crée des flux avec un en-tête zlib, et sur inflate ne reconnaît pas les différents en-têtes gzip sauf si vous le lui dites. Bien que cela soit documenté à partir de la version 1.2.1 du zlib.hfichier d'en-tête, ce n'est pas dans le manuel zlib . Depuis le fichier d'en-tête:
windowBitspeut également être supérieur à 15 pour le décodage gzip facultatif. Ajoutez 32 à windowBitspour activer le décodage zlib et gzip avec détection automatique des en-têtes, ou ajoutez 16 pour décoder uniquement le format gzip (le format zlib renverra a Z_DATA_ERROR). Si un flux gzip est en cours de décodage, strm->adlerest un crc32 au lieu d'un adler32.
Merci, c'était très frustrant jusqu'à ce que je trouve ce message.
Alex le
Wow, c'est la question de 2009. Merci @Greg Hewgill
YuAn Shaolin Maculelê Lai
Peut-être pouvez-vous fournir quelques directives pour la décompression itérative du flux gzip. Dans la décompression gzip one-shot où votre flux de sortie et votre taille doivent être fixes et suffisants pour stocker toute la sortie décompressée. Cette valeur dépend de l'efficacité de la décompression gzip qui peut varier en fonction de l'entropie des données. Existe-t-il un moyen d'allouer dynamiquement plus d'espace au tampon de sortie en cas de besoin? Merci
pourquoi cette pièce d'or n'est pas sur la documentation sur ce format exactement?
Ramon Moraes
N'hésitez pas à envoyer une pull request / patch contre cpython en utilisant l'une de ces réponses.
dnozay
excellente réponse pour les chaînes, une idée comment faire cela pour un flux sans lire le fichier entier en mémoire?
Josh J
Je vous remercie. Je peux résoudre mon problème de décompression dans mon code source avec votre réponse.
Bethlee
incroyable, c'est une pépite d'or .. mais je ne peux pas m'empêcher de penser que ce sont des «nombres magiques»? où est-ce mentionné dans la documentation? J'ai regardé, mais je dois vraiment pas avoir vérifié assez dur .. aussi, la notation que je ne suis pas entièrement. Que signifie le | signifie, est-ce facultatif? et pourquoi le dégonflage est négatif .. MAX_WBITS est-il une constante .. 🙁
m1nkeh
3
La structure de zlib et gzip est différente. zlib utilise la RFC 1950 et gzip utilise la RFC 1952 , donc ont des en-têtes différents mais le reste a la même structure et suit la RFC 1951 .
zlib.decompress(data, 15 + 32)
python
zlib
la bibliothèque prend en charge :zlib
format compressé)deflate
format compressé)gzip
format compressé)Le
zlib
module python les supportera également.choisir windowBits
Mais
zlib
peut décompresser tous ces formats:deflate
format, utilisezwbits = -zlib.MAX_WBITS
zlib
format, utilisezwbits = zlib.MAX_WBITS
gzip
format, utilisezwbits = zlib.MAX_WBITS | 16
Voir la documentation sur http://www.zlib.net/manual.html#Advanced (section
inflateInit2
)exemples
données de test:
test évident pour
zlib
:tester pour
deflate
:tester pour
gzip
:les données sont également compatibles avec le
gzip
module:détection automatique des en-têtes (zlib ou gzip)
l'ajout
32
àwindowBits
déclenchera la détection d'en-têteutiliser à la
gzip
placePour les
gzip
données avec en-tête gzip, vous pouvez utilisergzip
directement le module; mais n'oubliez pas que sous le capot ,gzip
utilisezlib
.la source
La structure de zlib et gzip est différente. zlib utilise la RFC 1950 et gzip utilise la RFC 1952 , donc ont des en-têtes différents mais le reste a la même structure et suit la RFC 1951 .
la source