Как распаковать поток gzip с помощью zlib?

файлы формата Gzip (созданные с помощью gzip программа, например) используйте алгоритм сжатия" deflate", который является тем же алгоритмом сжатия, что и what zlib использует. Однако при использовании zlib для раздувания сжатого файла gzip библиотека возвращает Z_DATA_ERROR.

Как я могу использовать zlib для распаковки файла gzip?

4 ответов


чтобы распаковать файл формата gzip с помощью zlib, вызовите inflateInit2 С windowBits параметр as 16+MAX_WBITS, например:

inflateInit2(&stream, 16+MAX_WBITS);

если вы этого не сделаете, zlib будет жаловаться на плохой формат потока. По умолчанию zlib создает потоки с заголовком zlib, а on inflate не распознает другой заголовок gzip, если вы этого не скажете. Хотя это документировано начиная с версии 1.2.1 от zlib.h файл заголовка, он не находится в ручной работы с zlib. Из заголовка файл:

windowBits также может быть больше 15 для дополнительного декодирования gzip. Добавлять 32 to windowBits включить декодирование zlib и gzip с автоматическим заголовком обнаружение или добавление 16 для декодирования только формата gzip (формат zlib будет возвратить Z_DATA_ERROR). Если поток gzip декодируется, strm->adler is а CRC32 в Вместо adler32.


питон

zlib библиотека поддерживает:

питон zlib модуль также будет поддерживать их.

выбор windowBits

но zlib смогите распаковать все те форматы:

  • to (de-)compress используйте wbits = -zlib.MAX_WBITS
  • to (de-)compress используйте wbits = zlib.MAX_WBITS
  • to (de-)compress используйте wbits = zlib.MAX_WBITS | 16

см. документацию в http://www.zlib.net/manual.html#Advanced (раздел inflateInit2)

примеры

тестовые данные:

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

очевидный тест для zlib:

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

структура zlib и gzip отличается. с zlib использует RFC 1950 и gzip использует RFC 1952, поэтому имеют разные заголовки, но остальные имеют одинаковую структуру и следуют за RFC 1951.


узел.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 };

установки zlib использование пряжи

yarn add zlib