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 

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

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


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

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

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

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

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

выбор оконных битов

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

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

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

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

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

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

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

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

В моем случае были декомпрессированные сообщения электронной почты, которые хранятся в базе данных 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)