Winzip无法在Windows上打开由python shutil.make_archive创建的存档。在ubuntu上,归档管理器没问题

时间:2012-10-02 20:03:31

标签: python django zip shutil

我正在尝试在django http响应中返回一个zip文件,代码类似于......

archive = shutil.make_archive('testfolder', 'zip', MEDIA_ROOT, 'testfolder')
response = HttpResponse(FileWrapper(open(archive)),
                           content_type=mimetypes.guess_type(archive)[0])
response['Content-Length'] = getsize(archive)
response['Content-Disposition'] = "attachment; filename=test %s.zip" % datetime.now()
return response

现在,当在ubuntu上执行此代码时,生成的下载文件打开时没有任何问题,但是当它在Windows上执行时,创建的文件无法在winzip中打开(提供错误'Unsupported Zip Format')。

这里有什么非常明显的东西吗? python代码不应该是可移植的吗?

修改

感谢J.F. Sebastian的评论......

创建存档没有问题,它正在将其读回请求中。所以,解决方案是改变我的代码的第二行,

response = HttpResponse(FileWrapper(open(archive)),
                           content_type=mimetypes.guess_type(archive)[0])

to,

response = HttpResponse(FileWrapper(open(archive, 'rb')),  # notice extra 'rb'
                           content_type=mimetypes.guess_type(archive)[0])

结帐,my answer to this question了解更多详情......

2 个答案:

答案 0 :(得分:1)

您编写的代码应该可以正常工作。我只是从你的代码片段运行以下行来生成一个zip文件,并且能够在Linux和Windows上提取。

archive = shutil.make_archive('testfolder', 'zip', MEDIA_ROOT, 'testfolder')

有一些有趣且具体的事情正在发生。我建议你检查以下内容:

  1. 使用只有一个内容的脚本在Django外部生成zip文件。然后尝试在Windows机器上提取它。这将帮助您排除与Django,Web服务器或浏览器相关的任何事情
  2. 如果有效,请仔细查看您压缩的文件夹中的内容。这些文件的名称中是否有任何有趣的字符,是否存在奇怪的文件类型或超长文件名。
  3. 在Windows和Linux上的zip文件上运行md5校验和,只是为了确保两个文件是逐字节相同的。排除可能发生的任何文件损坏。

答案 1 :(得分:1)

感谢J.F. Sebastian的评论......

我仍然会在这里详细编写解决方案......

创建存档没有问题,它正在将其读回请求中。所以,解决方案是改变我的代码的第二行,

response = HttpResponse(FileWrapper(open(archive)),
                           content_type=mimetypes.guess_type(archive)[0])

to,

response = HttpResponse(FileWrapper(open(archive, 'rb')),  # notice extra 'rb'
                           content_type=mimetypes.guess_type(archive)[0])

因为显然隐藏在openopen(file, 'rb')的某处:

  

最常用的模式值是'r'表示读数,'w'表示   写(截断文件,如果它已经存在),和'a'为   追加(在某些Unix系统上意味着所有写入附加到   无论当前的搜索位置如何,文件的结尾都是如此。如果模式   省略,默认为'r'。默认是使用文本模式,即   可以将'\ n'字符转换为特定于平台的表示   写作和回读。 因此,打开二进制文件时,你   应该将“b”附加到模式值以在二进制模式下打开文件,   将提高可移植性(附加'b'即使有用也很有用   不以不同方式处理二进制文件和文本文件的系统   作为文档。)有关模式的更多可能值,请参见下文。

因此,简单来说,在阅读二进制文件时,使用{{1}}可以提高代码的可移植性(在这种情况下肯定会这样做)

现在,它在Windows上没有麻烦地提取......