Python zipfile.ZipFile 压缩损坏的文件

发布于 2025-01-20 23:28:15 字数 1044 浏览 2 评论 0原文

我有一个 Django 视图,用户可以调用它来调用本地服务器上的 zip 文件。它使用 zipfile.ZipFile 将多个文件压缩为一个 zip,如下所示:

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

然后我将此文件返回给用户作为响应:

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

但是下载的文件已损坏,我无法使用 ubuntu archive 打开它经理。

然后,当我尝试在 django 服务器中使用具有相同包的 python 解压缩文件时,我仍然收到错误:

with ZipFile(file_path, 'r') as zip_ref:
            zip_ref.extractall(my_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

知道我在这里做错了什么吗?

I have a Django view which users can call to zip files at my local server. It uses zipfile.ZipFile to compresses multiple files into a single zip as follows:

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

Then I return this file to the user in response:

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

But the downloaded file is corrupt, I can't open it using ubuntu archive manager.

Then when i try to unzip the file using python with the same package in my django server, I still get the error:

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

The error I get is:

  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

Any idea what am I doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

好多鱼好多余 2025-01-27 23:28:16

这应该是一个评论,但我认为它太长了。

我认为你应该看看你的路径,因为错误的路径可能会导致不必要的行为。从 zipfile 写入

归档名称应该相对于归档根目录,即它们不应该以路径分隔符开头。

以及来自zipfile extractc(全部)

如果成员文件名是绝对路径,则驱动器/UNC 共享点和前导(反)斜杠将被删除,例如: ///foo/bar 在 Unix 上变为 foo/bar,而 C:\foo\bar 变为Windows 上的 foo\bar。并且成员文件名中的所有“..”组件将被删除,例如:../../foo../../ba..r 变为 foo../ba..r。在 Windows 上,非法字符(:、<、>、|、"、? 和 *)替换为下划线 (_)。

因此请确保 Shure 使用正确的路径。并确保 Shure 中没有有问题的字符(例如通配符 )或反斜杠)像这里

也许你应该用其他(un -) zip Tootls 看看是否有区别,有时它们更具体(像这里

This should be a comment, but i think it's to long.

I think you should have a look at your paths, because wrong path can lead to unwanted behaviour. From the zipfile write:

Archive names should be relative to the archive root, that is, they should not start with a path separator.

and from zipfile extratc (all):

If a member filename is an absolute path, a drive/UNC sharepoint and leading (back)slashes will be stripped, e.g.: ///foo/bar becomes foo/bar on Unix, and C:\foo\bar becomes foo\bar on Windows. And all ".." components in a member filename will be removed, e.g.: ../../foo../../ba..r becomes foo../ba..r. On Windows illegal characters (:, <, >, |, ", ?, and *) replaced by underscore (_).

So make shure you use a correct path. And make shure they do not have problematic characters (like wildcards or backslashes) like here

Maybe you should test with other (un-) zip tootls to see if it makes a difference, Sometimes they are more concrete (Like here)

瑾兮 2025-01-27 23:28:16

您可以尝试这样的事情。

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

you can try something like this.

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
佞臣 2025-01-27 23:28:16

创建httpresponse时,以二进制模式打开zip文件,以避免newline转换的错误:

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

Open the zip file in binary mode when creating the HttpResponse to avoid errors whith newline conversion:

folder_file = open(full_path, "rb")
        response = HttpResponse(FileWrapper(folder_file), content_type='application/zip')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文