«Неверное магическое число для заголовка файла» для работы составного zip-файла с использованием zipfile в Python 3.7 - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь использовать библиотеку 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-файл по адресу по этой ссылке здесь . Есть идеи, что делать?

...