Файлы формата Gzip (например, созданные с помощью gzipпрограммы) используют алгоритм сжатия deflate, который является тем же алгоритмом сжатия, что и zlib . Однако при использовании zlib для расширения файла, сжатого с помощью gzip, библиотека возвращает файл Z_DATA_ERROR.
Как я могу использовать zlib для распаковки файла gzip?
Чтобы распаковать файл в формате gzip с помощью zlib, вызовите inflateInit2с windowBitsпараметром as 16+MAX_WBITS, например:
inflateInit2(&stream, 16+MAX_WBITS);
Если вы этого не сделаете, zlib будет жаловаться на неправильный формат потока. По умолчанию zlib создает потоки с заголовком zlib, а при inflate не распознает другой заголовок gzip, если вы этого не укажете. Хотя это задокументировано, начиная с версии 1.2.1 zlib.hфайла заголовка, в руководстве по zlib этого нет . Из файла заголовка:
windowBitsтакже может быть больше 15 для необязательного декодирования gzip. Добавьте 32, чтобы windowBitsвключить декодирование zlib и gzip с автоматическим определением заголовка, или добавьте 16, чтобы декодировать только формат gzip (формат zlib вернет a Z_DATA_ERROR). Если декодируется поток gzip, strm->adlerэто crc32 вместо adler32.
Спасибо, это было очень неприятно, пока я не нашел этот пост.
Alex
Вау, это вопрос 2009 года. Спасибо @Greg Hewgill
YuAn Shaolin Maculelê Lai
Возможно, вы сможете дать некоторые рекомендации по итеративной распаковке потока gzip. При однократной декомпрессии gzip, когда выходной поток и размер должны быть фиксированными и достаточными для хранения всего распакованного вывода. Это значение зависит от эффективности распаковки gzip, которая может варьироваться в зависимости от энтропии данных. Есть ли способ динамически выделять больше места для выходного буфера при необходимости? Спасибо
почему этой золотой монеты нет в документации именно в этом формате?
Рамон Мораес
пожалуйста, не стесняйтесь отправлять запрос на перенос / исправление для cpython, используя любой из этих ответов.
dnozay
отличный ответ для строк, есть идеи, как это сделать для потока, не читая весь файл в память?
Josh J
Спасибо. Я могу решить мою проблему распаковки в исходном коде с вашим ответом.
Bethlee
невероятно, это золотой самородок ... но я не могу не чувствовать, что это равносильно «волшебным числам»? где в документации это упоминается? Я посмотрел, но, должно быть, действительно недостаточно тщательно проверил ... Кроме того, обозначения, которые я не полностью следую. Что значит | значит, это необязательно? и почему deflate отрицательный .. является ли MAX_WBITS постоянным .. 🙁
m1nkeh
3
Структура zlib и gzip различна. zlib использует RFC 1950, а gzip использует RFC 1952 , поэтому имеют разные заголовки, но остальные имеют одинаковую структуру и следуют RFC 1951 .
zlib.decompress(data, 15 + 32)
питон
zlib
библиотека поддерживает :zlib
сжатый формат)deflate
сжатый формат)gzip
сжатый формат)Модуль python
zlib
также поддерживает их.выбор windowBits
Но
zlib
может распаковать все эти форматы:deflate
формата используйтеwbits = -zlib.MAX_WBITS
zlib
формата используйтеwbits = zlib.MAX_WBITS
gzip
формата используйтеwbits = zlib.MAX_WBITS | 16
См. Документацию в http://www.zlib.net/manual.html#Advanced (раздел
inflateInit2
)Примеры
данные испытаний:
очевидный тест на
zlib
:тест на
deflate
:тест на
gzip
:данные также совместимы с
gzip
модулем:автоматическое определение заголовка (zlib или gzip)
добавление
32
кwindowBits
вызовет обнаружение заголовкаиспользуя
gzip
вместоДля
gzip
данных с заголовком gzip вы можете использоватьgzip
модуль напрямую; но , пожалуйста , помните , что под капотом ,gzip
использованиеzlib
.источник
Структура zlib и gzip различна. zlib использует RFC 1950, а gzip использует RFC 1952 , поэтому имеют разные заголовки, но остальные имеют одинаковую структуру и следуют RFC 1951 .
источник