Domanda

file formato gzip (creati con il programma gzip, per esempio) utilizzano l'algoritmo di compressione "sgonfia", che è lo stesso algoritmo di compressione come quello che zlib utilizza. Tuttavia, quando si utilizza zlib per gonfiare un file compresso con gzip, la biblioteca restituisce un Z_DATA_ERROR.

Come posso utilizzare zlib per decomprimere un file gzip?

È stato utile?

Soluzione

Per decomprimere un file in formato gzip con zlib, chiamare inflateInit2 con il parametro windowBits come 16+MAX_WBITS, in questo modo:

inflateInit2(&stream, 16+MAX_WBITS);

Se non si esegue questa operazione, zlib si lamenta perché un formato di flusso male. Per impostazione predefinita, zlib crea flussi di testa zlib, e gonfiare non riconosce la diversa intestazione gzip a meno che non gli si dice così. Anche se questo è documentato a partire dalla versione 1.2.1 del file di intestazione zlib.h, non è nel zlib . Dal file di intestazione:

  

windowBits può anche essere maggiore di 15 per la decodifica gzip opzionale. Inserisci      32 a windowBits per consentire zlib e gzip decodifica con intestazione automatica      rilevamento, o aggiungere 16 per decodificare solo il formato gzip (il formato sarà zlib      restituire un Z_DATA_ERROR). Se un flusso gzip viene decodificato, strm->adler è      un CRC32 invece di un Adler32.

Altri suggerimenti

python

zlib libreria supporta :

Il modulo python zlib sosterrà questi pure.

windowBits scegliendo

Ma zlib può decomprimere tutti questi formati:

  • (dis) comprimere formato deflate, uso wbits = -zlib.MAX_WBITS
  • (dis) comprimere formato zlib, uso wbits = zlib.MAX_WBITS
  • (dis) comprimere formato gzip, uso wbits = zlib.MAX_WBITS | 16

Si veda la documentazione in http://www.zlib.net/manual.html#Advanced (sezione inflateInit2)

esempi

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

prova evidente per zlib:

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

prova per 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'

prova per 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'

i dati è inoltre compatibile con il modulo gzip:

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

rilevazione automatica di intestazione (zlib o gzip)

aggiungendo 32 a windowBits attiverà il rilevamento di intestazione

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

utilizzando gzip invece

Per i dati gzip con intestazione gzip è possibile utilizzare il modulo gzip direttamente; ma si ricorda che sotto il cofano , gzip utilizza zlib.

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

La struttura di zlib e gzip è diverso. zlib utilizza RFC 1950 e gzip usi RFC 1952 , in modo da avere intestazioni diverse, ma il resto hanno la stessa struttura e segue 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 };

Si installa zlib usando filato

yarn add zlib
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top