Pergunta

arquivos de formato Gzip (criado com o programa gzip, por exemplo) usar o algoritmo de compressão "deflate", que é o mesmo algoritmo de compressão como o zlib usos. Entretanto, ao usar zlib para inflar um arquivo gzip comprimido, os retornos de biblioteca um Z_DATA_ERROR.

Como posso usar zlib para descompactar um arquivo gzip?

Foi útil?

Solução

Para descompactar um arquivo em formato gzip com zlib, chamada inflateInit2 com o parâmetro windowBits como 16+MAX_WBITS, como este:

inflateInit2(&stream, 16+MAX_WBITS);

Se você não fizer isso, zlib vai reclamar de um formato de fluxo ruim. Por padrão, zlib cria fluxos de cabeça zlib, e em inflar não reconhece o diferente cabeçalho gzip a menos que você diga a ele por isso. Embora este está documentada a partir da versão 1.2.1 do arquivo de cabeçalho zlib.h, não é na href="http://www.zlib.net/manual.html#inflateInit2" rel="noreferrer"> manual do . A partir do arquivo de cabeçalho:

windowBits também pode ser maior do que 15 para a descodificação gzip opcional. Adicionar 32 a windowBits para permitir zlib e gzip descodificar com cabeçalho automática detecção, ou adicionar 16 para decodificar apenas o formato gzip (o formato zlib vontade retornar um Z_DATA_ERROR). Se um fluxo gzip está sendo decodificado, strm->adler é um crc32 em vez de um Adler32.

Outras dicas

python

zlib biblioteca suporta :

O módulo python zlib apoiará estes também.

windowBits escolhendo

Mas zlib pode descompactar todos os formatos:

  • para (des) compressa deflate formato, uso wbits = -zlib.MAX_WBITS
  • para (des) compressa zlib formato, uso wbits = zlib.MAX_WBITS
  • para (des) compressa gzip formato, uso wbits = zlib.MAX_WBITS | 16

Veja a documentação em http://www.zlib.net/manual.html#Advanced (seção inflateInit2)

exemplos

Os dados do teste:

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

teste óbvia para zlib:

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

teste para 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'

teste para 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'

Os dados também é compatível com o módulo gzip:

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

detecção automática da cabeça (zlib ou gzip)

adicionando 32 para windowBits irá desencadear cabeçalho detecção

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

usando gzip vez

Para dados gzip com cabeçalho gzip você pode usar módulo gzip diretamente; mas lembre-se que sob o capô , gzip usa zlib.

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

A estrutura do zlib e gzip é diferente. zlib usos RFC 1950 e gzip usos RFC 1952 , por isso têm diferentes cabeçalhos mas o resto tem a mesma estrutura e segue o 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 };

Você instala zlib usando fio

yarn add zlib
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top