web-dev-qa-db-fra.com

décompresser le fichier dans "BadZipFile: le fichier n'est pas un fichier Zip"

J'ai deux fichiers Zip, les deux s'ouvrent bien avec Windows Explorer et 7-Zip. 

Cependant, lorsque je les ouvre avec le module zipfile de Python [zipfile.ZipFile ("filex.Zip")], l’un d’eux s’ouvre mais l’autre donne l’erreur "BadZipfile: File is not a Zip file".

Je me suis assuré que ce dernier est un fichier Zip valide en l'ouvrant avec 7-Zip et en regardant ses propriétés (dit 7Zip.ZIP). Lorsque j'ouvre le fichier avec un éditeur de texte, les deux premiers caractères sont "PK", ce qui montre qu'il s'agit bien d'un fichier Zip.

J'utilise Python 2.5 et je ne sais vraiment pas comment s'y prendre. Je l'ai essayé à la fois avec Windows et Ubuntu et le problème existe sur les deux plates-formes.

Mise à jour: Traceback à partir de Python 2.5.4 sous Windows:

Traceback (most recent call last):
File "<module1>", line 5, in <module>
    zipfile.ZipFile("c:/temp/test.Zip")
File "C:\Python25\lib\zipfile.py", line 346, in init
    self._GetContents()
File "C:\Python25\lib\zipfile.py", line 366, in _GetContents
    self._RealGetContents()
File "C:\Python25\lib\zipfile.py", line 378, in _RealGetContents
    raise BadZipfile, "File is not a Zip file"
BadZipfile: File is not a Zip file

Fondamentalement, lorsque la fonction _EndRecData est appelée pour obtenir des données de l'enregistrement "End of Central Directory", la vérification de la longueur des commentaires échoue [endrec [7] == len (comment)]. 

Les valeurs des sections locales dans la fonction _EndRecData sont les suivantes:

 END_BLOCK: 4096,
 comment: '\x00',
 data: '\xd6\xf6\x03\x00\x88,N8?<e\xf0q\xa8\x1cwK\x87\x0c(\x82a\xee\xc61N\'1qN\x0b\x16K-\x9d\xd57w\x0f\xa31n\xf3dN\x9e\xb1s\xffu\xd1\.....', (truncated)
 endrec: ['PK\x05\x06', 0, 0, 4, 4, 268, 199515, 0],
 filesize: 199806L,
 fpin: <open file 'c:/temp/test.Zip', mode 'rb' at 0x045D4F98>,
 start: 4073
33
sharjeel

la solution d'astronautlevel fonctionne dans la plupart des cas, mais les données compressées et les CRC du fichier Zip peuvent également contenir les mêmes 4 octets. Vous devriez faire une rfind (pas find), chercher à pos + 20 puis ajouter write \x00\x00 à la fin du fichier (indiquez aux applications Zip que la longueur de la section 'comments' est de 0 octets).


    # HACK: See http://bugs.python.org/issue10694
    # The Zip file generated is correct, but because of extra data after the 'central directory' section,
    # Some version of python (and some Zip applications) can't read the file. By removing the extra data,
    # we ensure that all applications can read the Zip without issue.
    # The Zip format: http://www.pkware.com/documents/APPNOTE/APPNOTE-6.3.0.TXT
    # Finding the end of the central directory:
    #   http://stackoverflow.com/questions/8593904/how-to-find-the-position-of-central-directory-in-a-Zip-file
    #   http://stackoverflow.com/questions/20276105/why-cant-python-execute-a-Zip-archive-passed-via-stdin
    #       This second link is only losely related, but echos the first, "processing a Zip archive often requires backwards seeking"
    content = zipFileContainer.read()
    pos = content.rfind('\x50\x4b\x05\x06') # reverse find: this string of bytes is the end of the Zip's central directory.
    if pos>0:
        zipFileContainer.seek(pos+20) # +20: see secion V.I in 'Zip format' link above.
        zipFileContainer.truncate()
        zipFileContainer.write('\x00\x00') # Zip file comment length: 0 byte length; tell Zip applications to stop reading.
        zipFileContainer.seek(0)

    return zipFileContainer
7
UltramaticOrange

Je rencontre le même problème. Mon problème était que c'était un gzip au lieu d'un fichier Zip. Je suis passé à la classe gzip.GzipFile et cela a fonctionné à merveille.

5
marsl

J'ai eu le même problème et j'ai pu résoudre ce problème pour mes fichiers, voir ma réponse à zipfile ne peux pas gérer un type de données Zip?

2
Uri Cohen

Affichez l'intégralité de la trace que vous avez obtenue de Python - ceci peut donner une indication quant à la nature du problème spécifique. Sans réponse: Quel logiciel a généré le mauvais fichier et sur quelle plate-forme?

Mise à jour: Traceback indique qu'un problème est survenu lors de la détection de l'enregistrement "Fin du répertoire central" dans le fichier - voir la fonction _EndRecData à partir de la ligne 128 de C:\Python25\Lib\zipfile.py

Suggestions:
(1) Trace à travers la fonction ci-dessus
(2) Essayez-le sur le dernier Python
(3) Répondez à la question ci-dessus.
(4) Lisez ceci et toute autre information trouvée par google("BadZipfile: File is not a Zip file") qui semble être pertinente

1
John Machin

Parfois, il existe des fichiers Zip contenant des fichiers corrompus et lors de la décompression, le fichier Zip génère une erreur de fichier incorrect. mais il existe des outils tels que 7Zip winrar qui ignore ces erreurs et décompresse avec succès le fichier Zip. vous pouvez créer un sous-processus et utiliser ce code pour décompresser votre fichier Zip sans obtenir d'erreur BadZipFile.

import subprocess
ziploc = "C:/Program Files/7-Zip/7z.exe" #location where 7Zip is installed
cmd = [ziploc, 'e',your_Zip_file.Zip ,'-o'+ OutputDirectory ,'-r' ] 
sp = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
0
vsnahar