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?
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()
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é).
Mais zlib
peut décompresser tous ces formats:
deflate
, utilisez wbits = -zlib.MAX_WBITS
zlib
, utilisez wbits = zlib.MAX_WBITS
gzip
, utilisez wbits = zlib.MAX_WBITS | 16
Voir la documentation dans http://www.zlib.net/manual.html#Advanced (section inflateInit2
)
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()
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'
gzip
à la placeou 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()
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.
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.
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)
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()