Я пытаюсь использовать библиотеку Python zipfile, чтобы разархивировать разделенный ZIP-файл, объединяя все разбиения файлов, а затем распаковывая конечный продукт, но я получаю сообщение об ошибке «Неверное магическое число для заголовка файла», используя эту библиотеку .
Я пишу скрипт Python, который обычно получает один ZIP-файл, но очень редко получает ZIP-файл, разбитый на несколько частей (например, foo.zip.001, foo.zip.002 и т. Д.). Из того, что я могу сказать, нет простого способа справиться с этим, если вам нужно связать скрипт с его зависимостями для контейнера Docker. Однако я наткнулся на этот SO-ответ , который объясняет, что вы можете объединить файлы в один ZIP-файл и рассматривать его как таковой. Так что мой план битвы состоит в том, чтобы объединить все разделенные файлы в один большой ZIP-файл, а затем распаковать этот файл. Я создал тестовый пример (с терминалом Mac), используя видеофайл с помощью следующей команды:
$ zip -s 5m test ch4_3.mp4
Вот мой код для объединения всех файлов:
import zipfile
split_files = ['test.z01', 'test.z02', 'test.z03', 'test.zip']
with open('test_video.zip', 'wb') as f:
for file in split_files:
with open(file, 'rb') as zf:
f.write(zf.read())
Если я иду к своему терминалу и запускаю unzip test_video.zip
, это вывод:
$ unzip test_video.zip
Archive: test_video.zip
warning [test_video.zip]: zipfile claims to be last disk of a multi-part archive;
attempting to process anyway, assuming all parts have been concatenated
together in order. Expect "errors" and warnings...true multi-part support
doesn't exist yet (coming soon).
warning [test_video.zip]: 15728640 extra bytes at beginning or within zipfile
(attempting to process anyway)
file #1: bad zipfile offset (local header sig): 15728644
(attempting to re-compensate)
inflating: ch4_3.mp4
Кажется, что он немного ударил по дороге, но он успешно работает. Однако, когда я пытаюсь запустить следующий код:
if not os.path.exists('output'):
os.mkdir('output')
with zipfile.ZipFile('tester/test_video.zip', 'r') as z:
z.extractall('output')
Я получаю следующую ошибку:
---------------------------------------------------------------------------
BadZipFile Traceback (most recent call last)
<ipython-input-60-07a6f56ea685> in <module>()
2 os.mkdir('output')
3 with zipfile.ZipFile('tester/test_video.zip', 'r') as z:
----> 4 z.extractall('output')
~/anaconda3/lib/python3.6/zipfile.py in extractall(self, path, members, pwd)
1499
1500 for zipinfo in members:
-> 1501 self._extract_member(zipinfo, path, pwd)
1502
1503 @classmethod
~/anaconda3/lib/python3.6/zipfile.py in _extract_member(self, member, targetpath, pwd)
1552 return targetpath
1553
-> 1554 with self.open(member, pwd=pwd) as source, 1555 open(targetpath, "wb") as target:
1556 shutil.copyfileobj(source, target)
~/anaconda3/lib/python3.6/zipfile.py in open(self, name, mode, pwd, force_zip64)
1371 fheader = struct.unpack(structFileHeader, fheader)
1372 if fheader[_FH_SIGNATURE] != stringFileHeader:
-> 1373 raise BadZipFile("Bad magic number for file header")
1374
1375 fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
BadZipFile: Bad magic number for file header
Если я попытаюсь запустить его с файлом .zip раньше других, вот что я получу:
split_files = ['test.zip', 'test.z01', 'test.z02', 'test.z03']
with open('test_video.zip', 'wb') as f:
for file in split_files:
with open(file, 'rb') as zf:
f.write(zf.read())
with zipfile.ZipFile('test_video.zip', 'r') as z:
z.extractall('output')
Вот вывод:
---------------------------------------------------------------------------
BadZipFile Traceback (most recent call last)
<ipython-input-14-f7aab706dbed> in <module>()
1 if not os.path.exists('output'):
2 os.mkdir('output')
----> 3 with zipfile.ZipFile('test_video.zip', 'r') as z:
4 z.extractall('output')
~/anaconda3/lib/python3.6/zipfile.py in __init__(self, file, mode, compression, allowZip64)
1106 try:
1107 if mode == 'r':
-> 1108 self._RealGetContents()
1109 elif mode in ('w', 'x'):
1110 # set the modified flag so central directory gets written
~/anaconda3/lib/python3.6/zipfile.py in _RealGetContents(self)
1173 raise BadZipFile("File is not a zip file")
1174 if not endrec:
-> 1175 raise BadZipFile("File is not a zip file")
1176 if self.debug > 1:
1177 print(endrec)
BadZipFile: File is not a zip file
Используя ответ на этот ТАК вопрос , я понял, что заголовок b'PK\x07\x08'
, но я не знаю почему. Я также использовал функцию testzip()
, и она указывает прямо на виновника: ch4_3.mp4
.
Вы можете найти соответствующий ZIP-файл по адресу по этой ссылке здесь . Есть идеи, что делать?