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')