Распаковка файлов приводит к "BadZipFile: файл не является zip файлом"
У меня есть два zip файла, оба из них хорошо открываются с помощью Проводника Windows и 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 (комментарий)].
Значения locals в функции _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
Ответы
Ответ 1
файлы с именем 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
Ответ 2
Решение astronautlevel работает в большинстве случаев, но сжатые данные и CRC в Zip также могут содержать те же 4 байта. Вы должны сделать rfind
(не find
), искать pos + 20, а затем добавить запись \x00\x00
в конец файла (скажите zip-приложениям, что длина раздела комментариев составляет 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 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
Ответ 3
Я столкнулся с той же проблемой. Моя проблема заключалась в том, что это был gzip вместо zip файла. Я переключился на класс gzip.GzipFile
, и он работал как шарм.
Ответ 4
У меня была такая же проблема и я смог решить эту проблему для своих файлов, см. мой ответ на
zipfile can not обрабатывает некоторые данные zip-данных?
Ответ 5
Покажите полную трассировку, полученную от Python - это может дать нам подсказку относительно конкретной проблемы. Без ответа:. Какое программное обеспечение создало плохой файл и на какой платформе?
Обновление: Traceback указывает на наличие проблемы с обнаружением записи "End of Central Directory" в файле - см. функцию _EndRecData, начиная со строки 128 из C:\Python25\Lib\zipfile.py
Предложения:
(1) Проследить описанную выше функцию
(2) Попробуйте на последнем Python
(3) Ответьте на вопрос выше.
(4) Прочитайте это и все, что найдено в google("BadZipfile: File is not a zip file")
, которое кажется релевантным
Ответ 6
Иногда существуют 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)
Ответ 7
Вы пробовали новый python, или если это слишком много проблем, просто новый zipfile.py? Я успешно использовал копию zipfile.py из Python 2.6.2 (последняя в то время) с Python 2.5, чтобы открыть некоторые zip файлы, которые не поддерживались модулем zipfile Py2.5s.