Question

fichiers au format Gzip (créés avec le programme gzip, par exemple) utilisent le "dégonfler" algorithme de compression, qui est le même algorithme de compression que zlib utilise. Cependant, lors de l'utilisation zlib pour gonfler un fichier compressé gzip, la bibliothèque retourne un Z_DATA_ERROR.

Comment puis-je utiliser zlib pour décompresser un fichier gzip?

Était-ce utile?

La solution

Pour décompresser un fichier au format gzip avec zlib, appelez inflateInit2 avec le paramètre windowBits comme 16+MAX_WBITS, comme ceci:

inflateInit2(&stream, 16+MAX_WBITS);

Si vous ne le faites pas, zlib se plaindre d'un mauvais format de flux. Par défaut, zlib crée des cours d'eau avec un en-tête de zlib, et gonflent ne reconnaît pas l'autre entête du fichier à moins que vous dire ainsi. Bien que cela soit documenté à partir de la version 1.2.1 du fichier d'en-tête de zlib.h, il est dans le manuel zlib . A partir du fichier d'en-tête:

  

windowBits peut aussi être supérieure à 15 pour le décodage gzip en option. Ajouter      32 à windowBits pour permettre zlib et gzip décodage avec tête automatique      détection, ou ajouter 16 à décoder uniquement le format gzip (le format zlib sera      retourner un Z_DATA_ERROR). Si un flux gzip est décodé, strm->adler est      un crc32 au lieu d'un adler32.

Autres conseils

python

bibliothèque zlib soutient :

Le module zlib python soutiendra ceux-ci ainsi.

choisir windowBits

Mais zlib peut décomprimer tous ces formats:

  • (dé) compression format deflate, utilisez wbits = -zlib.MAX_WBITS
  • (dé) compression format zlib, utilisez wbits = zlib.MAX_WBITS
  • (dé) compression format gzip, utilisez wbits = zlib.MAX_WBITS | 16

Voir la documentation en http://www.zlib.net/manual.html#Advanced (section inflateInit2)

Exemples

données de test:

>>> 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()
>>> 

Test évident pour zlib:

>>> zlib.decompress(zlib_data)
'test'

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'

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'

les données est également compatible avec le module gzip:

>>> import gzip
>>> import StringIO
>>> fio = StringIO.StringIO(gzip_data)
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
'test'
>>> f.close()

Détection automatique d'en-tête (zlib ou gzip)

ajouter 32 à windowBits déclenche la détection d'en-tête

>>> zlib.decompress(gzip_data, zlib.MAX_WBITS|32)
'test'
>>> zlib.decompress(zlib_data, zlib.MAX_WBITS|32)
'test'

en utilisant à la place gzip

Pour les données de gzip avec en-tête de gzip, vous pouvez utiliser le module de gzip directement; mais s'il vous plaît rappelez-vous que sous le capot , gzip utilise zlib.

fh = gzip.open('abc.gz', 'rb')
cdata = fh.read()
fh.close()

La structure de zlib et gzip est différent. zlib utilise RFC 1950 et utilise gzip RFC 1952 , donc des en-têtes différents, mais les autres ont la même structure et suit la 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 };

Vous installez le fil à l'aide zlib

yarn add zlib
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top