Python zipfile.ZipFile запечатывает поврежденный файл

У меня есть представление Django, которое пользователи могут вызывать, чтобы застегнуть файлы на моем локальном сервере. Оно использует zipfile.ZipFile для сжатия нескольких файлов в один zip следующим образом:

with ZipFile(env_dir + 'folder.zip', 'w') as zipObj:
                zipObj.write(dir + '1.json')
                zipObj.write(dir + '2.json')

Затем я возвращаю этот файл пользователю в ответ:

folder_file = open(full_path, "r", encoding='Cp437')
            response = HttpResponse(FileWrapper(folder_file), content_type='application/zip')

Но скачанный файл поврежден, я не могу открыть его с помощью менеджера архивов ubuntu.

Затем, когда я пытаюсь разархивировать файл с помощью python с тем же пакетом на моем сервере django, я все еще получаю ошибку:

with ZipFile(file_path, 'r') as zip_ref:
            zip_ref.extractall(dir)

Ошибка, которую я получаю:

  File ".../views.py", line 38, in post
    with ZipFile(file_path, 'r') as zip_ref:
  File "/usr/lib/python3.8/zipfile.py", line 1269, in __init__
    self._RealGetContents()
  File "/usr/lib/python3.8/zipfile.py", line 1354, in _RealGetContents
    fp.seek(self.start_dir, 0)
OSError: [Errno 22] Invalid argument

Есть идеи, что я делаю не так?

Это должен быть комментарий, но я думаю, что он слишком длинный.

Я думаю, вам следует посмотреть на ваши пути, потому что неправильный путь может привести к нежелательному поведению. Из файла zipfile напишите:

Имена архивов должны быть относительными к корню архива, то есть не должны начинаться с разделителя путей.

и из zipfile extratc (all):

Если имя файла-члена является абсолютным путем, диск/UNC sharepoint и ведущие (обратные) косые черты будут удалены, например: ///foo/bar становится foo/bar на Unix, а C:\foo\bar становится foo\bar на Windows. И все "." компоненты в имени файла-члена будут удалены, например: ../../foo../../ba..r становится foo../ba..r. В Windows недопустимые символы (:, <, >, |, ", ?, и *) заменяются подчеркиванием (_).

.

Так что убедитесь, что вы используете правильный путь. И убедитесь, что они не содержат проблемных символов (таких как символы подстановки или обратные слеши) , как здесь

Может быть, вам следует протестировать с другими (не-) зип-тотлами, чтобы увидеть, имеет ли это значение, Иногда они более конкретны (Как здесь)

вы можете попробовать что-то вроде этого.

zipf = ZipFile("whatever.zip", "w")

for file in files_to_add:
    this_file = urlopen(file).read()
    this_filename = 'file name.json'
    zipf.writestr(this_filename, this_file)

zipf.close()

response = HttpResponse(io.open("whatever.zip", mode="rb").read(), content_type="application/zip")
response["Content-Disposition"] = "attachment; filename=whatever_name_you_want.zip"

return response

Откройте zip-файл в двоичном режиме при создании HttpResponse, чтобы избежать ошибок при преобразовании новой строки:

folder_file = open(full_path, "rb")
        response = HttpResponse(FileWrapper(folder_file), content_type='application/zip')
Вернуться на верх