无法使用 zipfile.ZIP_DEFLATED 压缩方法提取由 Python 创建的 ZIP 文件
Unable to extract ZIP file created with Python using zipfile.ZIP_DEFLATED compression method
我有两个程序(一个在 Java 中,一个在 Python 中)压缩文件夹,将其上传到 WebServer 并在它们上触发解压缩方法。
程序的 Java 版本没有问题,文件在服务器上提取也没有问题。
我在这里使用 ArchiveStreamFactory class 即 new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP, this.currentOutputStream);
Python 版本仅在我使用 zipfile.ZIP_STORED
方法(不压缩文件)时有效。如果我使用 zipfile.ZIP_DEFLATED
方法,我会收到内部服务器错误。
我无法访问服务器,所以为此我只能依靠我这边能够弄清楚的东西。
Java 程序似乎确实使用了 ZIP_DEFLATED 方法,因为存档被压缩(更小)而不仅仅是存储。
我还在两个档案中 运行 zipinfo
(使用 Java 创建的和 Python 使用 DEFLATE 创建的 - 这不起作用) 也看看有什么不同。
这是输出:
# Java
-rw---- 2.0 fat 14398 bl defN 4-Jun-15 13:55 somefile.txt
# Python
-rw-r--r-- 2.0 unx 183 b- defN 28-Jun-15 21:39 someotherfile.txt
两者似乎都是用 DEFLATE (defN) 方法压缩的,那么为什么 Java 生成的存档有效而 Python 生成的存档无效?
所以经过大量调试和反复试验后,我发现了这个问题,以防其他人有兴趣或会遇到同样的问题。
我也将文件夹添加到 zip 中,看起来它不喜欢用 ZIP_DEFLATED 压缩的文件夹。我所做的是手动将文件夹的压缩设置为 ZIP_STORED,将文件的压缩设置为 ZIP_DEFLATED,然后它就可以工作了。有趣的是 Java 如何知道在幕后自动执行此操作,或者至少我猜它确实如此,因为 Java 版本有点相同(遍历 folders/files 并将它们添加到 ZIP ) 除了我只使用默认值(所以我从来没有为任何东西明确设置压缩类型)。
基本上我的代码(不起作用的版本)是这样的:
for dir_path, dir_names, file_names in os.walk(absolute_folder_path, compression=zipfile.ZIP_DEFLATED):
...
# Add folder to ZIP
f_zip.write(absolute_dir_path, arcname=relative_dir_path)
for file_name in file_names:
...
# Add file to ZIP
f_zip.write(absolute_file_path, arcname=relative_file_path)
修复是这个:
for dir_path, dir_names, file_names in os.walk(absolute_folder_path):
...
# Add folder to ZIP
f_zip.write(absolute_dir_path, arcname=relative_dir_path, compress_type=zipfile.ZIP_STORED)
for file_name in file_names:
...
# Add file to ZIP
f_zip.write(absolute_file_path, arcname=relative_file_path, compress_type=zipfile.ZIP_DEFLATED)
我有两个程序(一个在 Java 中,一个在 Python 中)压缩文件夹,将其上传到 WebServer 并在它们上触发解压缩方法。
程序的 Java 版本没有问题,文件在服务器上提取也没有问题。
我在这里使用 ArchiveStreamFactory class 即 new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP, this.currentOutputStream);
Python 版本仅在我使用 zipfile.ZIP_STORED
方法(不压缩文件)时有效。如果我使用 zipfile.ZIP_DEFLATED
方法,我会收到内部服务器错误。
我无法访问服务器,所以为此我只能依靠我这边能够弄清楚的东西。
Java 程序似乎确实使用了 ZIP_DEFLATED 方法,因为存档被压缩(更小)而不仅仅是存储。
我还在两个档案中 运行 zipinfo
(使用 Java 创建的和 Python 使用 DEFLATE 创建的 - 这不起作用) 也看看有什么不同。
这是输出:
# Java
-rw---- 2.0 fat 14398 bl defN 4-Jun-15 13:55 somefile.txt
# Python
-rw-r--r-- 2.0 unx 183 b- defN 28-Jun-15 21:39 someotherfile.txt
两者似乎都是用 DEFLATE (defN) 方法压缩的,那么为什么 Java 生成的存档有效而 Python 生成的存档无效?
所以经过大量调试和反复试验后,我发现了这个问题,以防其他人有兴趣或会遇到同样的问题。
我也将文件夹添加到 zip 中,看起来它不喜欢用 ZIP_DEFLATED 压缩的文件夹。我所做的是手动将文件夹的压缩设置为 ZIP_STORED,将文件的压缩设置为 ZIP_DEFLATED,然后它就可以工作了。有趣的是 Java 如何知道在幕后自动执行此操作,或者至少我猜它确实如此,因为 Java 版本有点相同(遍历 folders/files 并将它们添加到 ZIP ) 除了我只使用默认值(所以我从来没有为任何东西明确设置压缩类型)。
基本上我的代码(不起作用的版本)是这样的:
for dir_path, dir_names, file_names in os.walk(absolute_folder_path, compression=zipfile.ZIP_DEFLATED):
...
# Add folder to ZIP
f_zip.write(absolute_dir_path, arcname=relative_dir_path)
for file_name in file_names:
...
# Add file to ZIP
f_zip.write(absolute_file_path, arcname=relative_file_path)
修复是这个:
for dir_path, dir_names, file_names in os.walk(absolute_folder_path):
...
# Add folder to ZIP
f_zip.write(absolute_dir_path, arcname=relative_dir_path, compress_type=zipfile.ZIP_STORED)
for file_name in file_names:
...
# Add file to ZIP
f_zip.write(absolute_file_path, arcname=relative_file_path, compress_type=zipfile.ZIP_DEFLATED)