了解要使用哪个软件包以及相应的文档可能会有些困惑,因为实际上有几个Python绑定到Zstandard库。
下面,我指的是Gregory Szorc的库,我是通过conda的默认渠道安装的:
conda install zstd
conda list zstd
尽管文档上说要使用pip安装(但除非没有其他方法,我不会这样做,因为我希望我的conda环境保持可用),我只是推测这个版本是G. Szorc的版本,基于在__init__.py文件中的注释。
"""Python interface to the Zstandard (zstd) compression library."""
from __future__ import absolute_import, unicode_literals
所以,我认为相应的文档在这里。
无论如何,在安装后进行快速测试:
import zstandard as zstd
with zstd.open('test.zstd', 'w') as f:
for i in range(10_000):
f.write(f'foo {i} bar\n')
with zstd.open('test.zstd', 'r') as f:
for i, line in enumerate(f):
if i % 1000 == 0:
print(f'line {i:4d}: {line}', end='')
产生:
line 0: foo 0 bar
line 1000: foo 1000 bar
line 2000: foo 2000 bar
line 3000: foo 3000 bar
line 4000: foo 4000 bar
line 5000: foo 5000 bar
line 6000: foo 6000 bar
line 7000: foo 7000 bar
line 8000: foo 8000 bar
line 9000: foo 9000 bar
注意事项:
如果文件是以二进制(而不是文本)编写的,则使用
mode='rb'
,与普通文件相同。底层文件始终以二进制模式编写,但如果我们在
open
中使用文本模式,那么根据
open
的文档,"(...)在文本模式下读取或写入时,返回一个
io.TextIOWrapper
。"
请注意,我使用的是
f
的迭代器,而不是
readlines()
。从内联文档字符串中,它们让人觉得
readlines()
返回文件中的一行列表,即整个文件都被读入内存。使用迭代器,更有可能只有文件的部分在任何时刻在内存中(在
zstd
的缓冲区中)。
然而,阅读
文档的这一部分,我对上述内容不太确定。请继续关注...(
编辑:经过实证测试,结果是正确的,请参见下文)。
附录
关于上述的注释2和注释3:我进行了实证测试,通过将行数更改为1亿,并比较了两个版本的内存使用情况(使用htop
):
流式版本
with zstd.open('test.zstd', 'r') as f:
for i, line in enumerate(f):
if i % 10_000_000 == 0:
print(f'line {i:8d}: {line}', end='')
--内存使用无突增。
Readlines版本
with zstd.open('test.zstd', 'r') as f:
for i, line in enumerate(f.readlines()):
if i % 10_000_000 == 0:
print(f'line {i:8d}: {line}', end='')
--内存使用增加了几个GB。
可能是与安装的版本(1.5.5)有关。