распаковка файла приводит к «BadZipFile: файл не является файлом zip» - PullRequest
36 голосов
/ 21 июня 2010

У меня есть два zip-файла, оба хорошо открываются в Windows Explorer и 7-zip.

Однако, когда я открываю их с помощью модуля zipfile в Python [zipfile.ZipFile ("filex.zip")], один из них открывается, а другой выдает ошибку "BadZipfile: File is not a zip file".

Я убедился, что последний является действительным Zip-файлом, открыв его с помощью 7-Zip и просмотрев его свойства (говорит 7Zip.ZIP). Когда я открываю файл в текстовом редакторе, первые два символа - это «PK», показывая, что это действительно zip-файл.

Я использую Python 2.5 и не знаю, как это сделать. Я пробовал как с Windows, так и с Ubuntu, и проблема существует на обеих платформах.

Обновление: Трассировка от Python 2.5.4 в 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

Обычно, когда вызывается функция _EndRecData для получения данных из записи «Конец центрального каталога», проверка длины комментария завершается неудачей [endrec [7] == len (comment)].

Значения местных жителей в функции _EndRecData следующие:

 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

Ответы [ 7 ]

12 голосов
/ 08 июля 2012

файлы с именем file могут запутать Python - попробуйте назвать его как-нибудь еще.если это STILL не работает, попробуйте этот код:

def fixBadZipfile(zipFile):  
 f = open(zipFile, 'r+b')  
 data = f.read()  
 pos = data.find('\x50\x4b\x05\x06') # End of central directory signature  
 if (pos > 0):  
     self._log("Trancating file at location " + str(pos + 22)+ ".")  
     f.seek(pos + 22)   # size of 'ZIP end of central directory record' 
     f.truncate()  
     f.close()  
 else:  
     # raise error, file is truncated  
9 голосов
/ 24 февраля 2014

Решение Astronautlevel работает в большинстве случаев, но сжатые данные и CRC в Zip могут также содержать те же 4 байта. Вы должны выполнить rfind (не find), выполнить поиск pos + 20, а затем добавить запись \x00\x00 в конец файла (сообщить zip-приложениям, что длина раздела 'comments' равна 0 байтам) .


    # 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
6 голосов
/ 18 сентября 2013

Я сталкиваюсь с той же проблемой.Моя проблема заключалась в том, что это был ZIP-файл вместо ZIP-файла.Я переключился на класс gzip.GzipFile, и он работал как шарм.

2 голосов
/ 18 сентября 2011

У меня была такая же проблема, и я смог решить эту проблему для своих файлов, см. Мой ответ в zipfile не может обработать какой-либо тип данных zip?

1 голос
/ 21 июня 2010

Показать полную трассировку, которую вы получили от Python - это может дать подсказку относительно конкретной проблемы. Без ответа: Каким программным обеспечением получен плохой файл и на какой платформе?

Обновление: Traceback указывает на проблему с обнаружением записи «Конец центрального каталога» в файле - см. Функцию _EndRecData, начинающуюся со строки 128 C: \ Python25 \ Lib \ zipfile.py

Предложения:
(1) Проследите через вышеуказанную функцию
(2) Попробуйте на последнем Python
(3) Ответьте на вопрос выше.
(4) Прочитайте это и все остальное, найденное google("BadZipfile: File is not a zip file"), которое представляется уместным

0 голосов
/ 31 января 2019

Иногда существуют zip-файлы, которые содержат поврежденные файлы, и после распаковки zip-файл выдает ошибку badzipfile. но есть такие инструменты, как 7zip winrar, который игнорирует эти ошибки и успешно распаковывает zip-файл. Вы можете создать подпроцесс и использовать этот код для распаковки вашего zip-файла без получения ошибки 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 голосов
/ 22 июня 2010

Вы пробовали новый Python, или, если это слишком много проблем, просто более новый zipfile.py?Я успешно использовал копию zipfile.py из Python 2.6.2 (последняя на тот момент) с Python 2.5, чтобы открыть некоторые zip-файлы, которые не поддерживаются модулем zipfile Py2.5s.

...