Python的zipfile模块似乎无法压缩我的文件。

96

我写了一个小助手函数:

import zipfile

def main(archive_list=[],zfilename='default.zip'):
    print zfilename
    zout = zipfile.ZipFile(zfilename, "w")
    for fname in archive_list:
        print "writing: ", fname
        zout.write(fname)
    zout.close()

if __name__ == '__main__':
    main()  

我的问题是所有文件都没有被压缩!文件大小都一样,实际上只是扩展名从“.xls”改为“.zip”而已。

我正在winXP sp2上运行python 2.5。

3个回答

184

这是因为ZipFile要求你指定压缩方法。如果你没有指定,它会默认使用zipfile.ZIP_STORED的压缩方法,该方法只会将文件存储而不压缩。您需要指定方法为zipfile.ZIP_DEFLATED。为此,您需要安装zlib模块(通常已默认安装)。

import zipfile

def main(archive_list=[],zfilename='default.zip'):
    print zfilename
    zout = zipfile.ZipFile(zfilename, "w", zipfile.ZIP_DEFLATED) # <--- this is the change you need to make
    for fname in archive_list:
        print "writing: ", fname
        zout.write(fname)
    zout.close()

if __name__ == '__main__':
    main()  

更新:根据文档(python 3.7)的说明,'compression'参数应该被指定以覆盖默认值,该默认值为ZIP_STORED。可用选项是ZIP_DEFLATED、ZIP_BZIP2或ZIP_LZMA,相应的库zlib、bz2或lzma应该可用。


53
太糟糕的默认设置!为什么?! - gabe
14
因为zlib模块并非始终可用,尤其是在沙盒安装中。 - Chinmay Kanchi
7
我也遇到了zip文件的同样问题。我承认我的错误是在尝试使用Python文档中的示例代码之前没有阅读相关文档。我认为示例代码应该包括ZIP_DEFLATED参数,以使其更易理解。 - marcin_koss
1
如果您在写入ZipFile时使用ZipInfo(),则还必须设置zip_info.compress_type = ZIP_DEFLATED - Jostein L

16

有一种非常简单的方法可以压缩 zip 格式,

使用 shutil.make_archive 库。

例如:

import shutil

shutil.make_archive(file_name, 'zip', file location after compression)

可以在这里查看更详细的文档:这里


1
感谢您发布这篇文章。这种方法可以轻松地对文件进行归档,而无需经过压缩的繁琐步骤。 这是一个很好的流程结束方式,需要将它们的数据倒出以进行记录保存。我使用此方法将约10行代码简化为3行。 - user3507825

15
希望这对某人有用。 我测试了所有的zip模式,并在两个数据集上进行了基准测试。第一个数据集小(约30 MB),另一个较大(~1.5 GB)。它们由各种类型的文件组成,使测试尽可能接近实际情况。我对每个数据集进行了两种方法的测试:比例和完全。每个测试都重复3次,以获得平均值。这些结果可能因您的设备而异,但我认为这仍是一个很好的起点。
我使用两种测试方法是因为我正在尝试制作自己的专业备份解决方案。比例方法创建更多的zip文件,但它允许我在必要时传输更小的数据包,例如只更改的内容。虽然这更加复杂,但现在并不重要。

The proportional method explanation

完整的方法就是直接压缩整个文件夹。

The complete method explanation

压缩比率计算:

大小差异 = 源文件大小 - 压缩文件大小

压缩比率 = (大小差异 * 100.0) / 源文件大小

基本上,这个数字越高越好。

每个zip归档文件都是这样初始化的:

# Mode tests
with zipfile.ZipFile(target_zip, 'w', compression_method) as ziph:

# Level tests
with zipfile.ZipFile(target_zip, 'w', compression_method, compresslevel=level) as ziph:

这里是结果:

research results

似乎无论使用何种方法,最优的压缩模式都是ZIP_DEFLATED。唯一更小的存档大小是使用ZIP_LZMA模式,但它只是原来大小的一小部分,并且对于大数据集需要花费8倍的时间。此外,我尝试使用相同的数据集和方法进行不同级别的压缩。但这次每个级别只运行了一次。

Research results

看起来ZIP_DEFLATED和ZIP_BIP2具有类似的压缩能力,但后者速度慢得多。对于大数据集,压缩级别1或2应该足够。将其增加更多对最终文件大小没有显着影响。如果工作量要求大量“小”zip文件,则最好使用级别9。它提供高压缩比,但需要与级别1相同的时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接