web-dev-qa-db-fra.com

zlib.error: Erreur -3 lors de la décompression: vérification d'en-tête incorrecte

J'ai un fichier gzip et j'essaie de le lire via Python comme ci-dessous:

import zlib

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

il jette cette erreur:

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

Comment puis-je le surmonter?

47
VarunVyas

Mise à jour : réponse de dnozay explique le problème et devrait être la réponse acceptée.


Essayez le module gzip, le code ci-dessous est directement issu de python docs .

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

Vous avez cette erreur:

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

Ce qui est probablement dû au fait que vous essayez de vérifier les en-têtes qui ne s'y trouvent pas, par exemple vos données suivent RFC 1951 (deflate format compressé) plutôt que RFC 1950 (zlib format compressé) ou RFC 1952 (gzip format compressé).

choix de windowBits

Mais zlib peut décompresser tous ces formats:

  • pour (dé-) compresser le format deflate, utilisez wbits = -zlib.MAX_WBITS
  • pour (dé-) compresser le format zlib, utilisez wbits = zlib.MAX_WBITS
  • pour (dé-) compresser le format gzip, utilisez wbits = zlib.MAX_WBITS | 16

Voir la documentation dans http://www.zlib.net/manual.html#Advanced (section inflateInit2)

exemples

données de test:

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

test évident pour zlib:

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

test pour 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'

test pour 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'

les données sont également compatibles avec le module 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()

détection automatique des en-têtes (zlib ou gzip)

ajouter 32 à windowBits déclenchera la détection d'en-tête

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

en utilisant gzip à la place

ou vous pouvez ignorer zlib et utiliser directement le module gzip; mais n'oubliez pas que sous le capot , gzip utilise zlib.

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

Je viens de résoudre le problème de "vérification d'en-tête incorrecte" lors de la décompression des données gzippées.

Vous devez définir -WindowBits => WANT_GZIP dans votre appel pour inflateInit2 (utilisez la version 2)

Oui, cela peut être très frustrant. Une lecture généralement superficielle de la documentation présente Zlib comme une API pour la compression Gzip, mais par défaut (n'utilisant pas les méthodes gz *), il ne crée ni ne décompresse le format Gzip. Vous devez envoyer cet indicateur documenté de manière peu visible.

3
user2475290

Pour décompresser les octets gzippés incomplets qui sont en mémoire, le réponse de dnozay est utile mais il manque le zlib.decompressobj appel que j'ai jugé nécessaire:

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

Notez que zlib.MAX_WBITS | 16 est 15 | 16 qui est 31. Pour des informations sur wbits, voir zlib.decompress .


Crédit: réponse de Yann Vernier qui note le zlib.decompressobj appel.

1
Acumenus

Mon cas était de décompresser les e-mails stockés dans la base de données Bullhorn. L'extrait est le suivant:

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)
1
Yury Bondarau

Curieusement, j'ai eu cette erreur en essayant de travailler avec l'API Stack Overflow en utilisant Python.

J'ai réussi à le faire fonctionner avec l'objet GzipFile du répertoire gzip, à peu près comme ceci:

import gzip

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

file_contents = gzip_file.read()
0
Paul D. Waite