为什么 Python zipfile 不提供与命令行 zip 相同的输出 .zip 文件大小?
Why does Python zipfile not give the same output .zip file size as command-line zip?
这里是zip
生成的文件大小:
$ seq 10000 > 1.txt
$ zip 1 1.txt
adding: 1.txt (deflated 54%)
$ ls -og 1.zip
-rw-r--r-- 1 22762 Aug 29 10:04 1.zip
这是一个等效的 python 脚本:
import zipfile
z = zipfile.ZipFile(sys.argv[1], 'w', zipfile.ZIP_DEFLATED)
fn = sys.argv[1]
z.writestr(zipfile.ZipInfo(fn), sys.stdin.read())
z.close()
生成的 zip 文件大小如下:
$ seq 10000 | ./main.py 2.zip 2.txt
$ ls -go 2.zip
-rw-r--r-- 1 49002 Aug 29 10:15 2.zip
有人知道为什么 python 版本生成的 zip 文件没有 zip
生成的那么小吗?
事实证明(在python 3中检查)当使用ZipInfo
时,writestr()
不会使用compression
和compresslevel
14=]。这是一个糟糕的 API 设计示例。应该设计好是否使用ZipInfo,总是使用构造函数中的compression
和compresslevel
。
When passing a ZipInfo instance as the zinfo_or_arcname parameter, the compression method used will be that specified in the compress_type member of the given ZipInfo instance. By default, the ZipInfo constructor sets this member to ZIP_STORED.
正因如此,原来post上显示的python代码基本没有压缩。因此,python代码生成的文件较大。
此API设计的另一个问题是构造函数中的参数compression
与.writestr()
的compress_type
相同,但它们的名称不同。这是另一个糟糕的设计。没有理由为同一个东西起不同的名字。
这里是zip
生成的文件大小:
$ seq 10000 > 1.txt
$ zip 1 1.txt
adding: 1.txt (deflated 54%)
$ ls -og 1.zip
-rw-r--r-- 1 22762 Aug 29 10:04 1.zip
这是一个等效的 python 脚本:
import zipfile
z = zipfile.ZipFile(sys.argv[1], 'w', zipfile.ZIP_DEFLATED)
fn = sys.argv[1]
z.writestr(zipfile.ZipInfo(fn), sys.stdin.read())
z.close()
生成的 zip 文件大小如下:
$ seq 10000 | ./main.py 2.zip 2.txt
$ ls -go 2.zip
-rw-r--r-- 1 49002 Aug 29 10:15 2.zip
有人知道为什么 python 版本生成的 zip 文件没有 zip
生成的那么小吗?
事实证明(在python 3中检查)当使用ZipInfo
时,writestr()
不会使用compression
和compresslevel
14=]。这是一个糟糕的 API 设计示例。应该设计好是否使用ZipInfo,总是使用构造函数中的compression
和compresslevel
。
When passing a ZipInfo instance as the zinfo_or_arcname parameter, the compression method used will be that specified in the compress_type member of the given ZipInfo instance. By default, the ZipInfo constructor sets this member to ZIP_STORED.
正因如此,原来post上显示的python代码基本没有压缩。因此,python代码生成的文件较大。
此API设计的另一个问题是构造函数中的参数compression
与.writestr()
的compress_type
相同,但它们的名称不同。这是另一个糟糕的设计。没有理由为同一个东西起不同的名字。