Подтвердить что ты не робот

Zlib.error: Ошибка -3 при распаковке: неправильная проверка заголовка

У меня есть файл gzip, и я пытаюсь прочитать его через Python, как показано ниже:

import zlib

do = zlib.decompressobj(16+zlib.MAX_WBITS)
fh = open('abc.gz', 'rb')
cdata = fh.read()
fh.close()
data = do.decompress(cdata)

он выдает эту ошибку:

zlib.error: Error -3 while decompressing: incorrect header check

Как я могу его преодолеть?

4b9b3361

Ответ 1

Обновить: dnozay answer объясняет проблему и должен быть принятым ответом.


Попробуйте модуль gzip, код ниже прямо из python docs.

import gzip
f = gzip.open('/home/joe/file.txt.gz', 'rb')
file_content = f.read()
f.close()

Ответ 2

У вас есть эта ошибка:

zlib.error: Error -3 while decompressing: incorrect header check

Что наиболее вероятно, потому что вы пытаетесь проверить заголовки, которых там нет, например, ваши данные следуют RFC 1951 (сжатый формат deflate), а не RFC 1950 (сжатый формат zlib) или RFC 1952 (сжатый формат gzip).

выбирая windowBits

Но zlib может распаковать все эти форматы:

  • чтобы (de-) сжать формат deflate, используйте wbits = -zlib.MAX_WBITS
  • чтобы (de-) сжать формат zlib, используйте wbits = zlib.MAX_WBITS
  • чтобы (de-) сжать формат gzip, используйте wbits = zlib.MAX_WBITS | 16 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'

тест на 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'

тест для 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'

данные также совместимы с модулем gzip:

>>> import gzip
>>> import StringIO
>>> fio = StringIO.StringIO(gzip_data)  # io.BytesIO for Python 3
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
'test'
>>> f.close()

автоматическое определение заголовка (zlib или gzip)

добавление 32 к windowBits вызовет обнаружение заголовка

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

используя вместо этого gzip

или вы можете игнорировать zlib и напрямую использовать модуль gzip; но, пожалуйста, помните, что под капотом gzip использует zlib.

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

Ответ 3

Я просто решил проблему с неправильной проверкой заголовка при распаковке gzipped-данных.

Вам нужно установить -WindowBits = > WANT_GZIP в свой призыв к inflateInit2 (используйте 2 версию)

Да, это может быть очень неприятно. Обычно мелкое чтение документации представляет Zlib как сжатие API для Gzip, но по умолчанию (не используя методы gz *) он не создает или не разжимает формат Gzip. Вы должны отправить этот не очень заметный документ.

Ответ 4

Мой случай состоял в том, чтобы распаковать почтовые сообщения, которые хранятся в базе данных Bullhorn. Фрагмент следующий:

import pyodbc
import zlib

cn = pyodbc.connect('connection string')
cursor = cn.cursor()
cursor.execute('SELECT TOP(1) userMessageID, commentsCompressed FROM BULLHORN1.BH_UserMessage WHERE DATALENGTH(commentsCompressed) > 0 ')



 for msg in cursor.fetchall():
    #magic in the second parameter, use negative value for deflate format
    decompressedMessageBody = zlib.decompress(bytes(msg.commentsCompressed), -zlib.MAX_WBITS)

Ответ 5

Как ни странно, у меня была эта ошибка при попытке работать с API с помощью Python.

Мне удалось заставить его работать с объектом GzipFile из каталога gzip, примерно так:

import gzip

gzip_file = gzip.GzipFile(fileobj=open('abc.gz', 'rb'))

file_contents = gzip_file.read()

Ответ 6

Чтобы распаковать неполные сжатые байты, которые находятся в памяти, полезен ответ dnozay, но он пропускает вызов zlib.decompressobj который я счел необходимым:

incomplete_decompressed_content = zlib.decompressobj(wbits=zlib.MAX_WBITS | 16).decompress(incomplete_gzipped_content)

Обратите внимание, что zlib.MAX_WBITS | 16 zlib.MAX_WBITS | 16 это 15 | 16 15 | 16 который равен 31. Для получения дополнительной информации о wbits см. zlib.decompress.


Кредит: ответ Яна Вернье, который отмечает вызов zlib.decompressobj.