compression.zstd
--- 与 Zstandard 格式兼容的压缩¶
在 3.14 版本加入。
源代码: Lib/compression/zstd/__init__.py
此模块提供了使用 Zstandard(或 zstd)压缩算法来压缩和解压缩数据的类和函数。zstd 手册将 Zstandard 描述为“一种快速的无损压缩算法,旨在实现 zlib 级别的实时压缩场景和更好的压缩率。”模块还包含一个文件接口,支持读写由 zstd 工具创建的 .zst
文件内容,以及原始的 zstd 压缩流。
compression.zstd
模块包含:
用于增量(解)压缩的
ZstdCompressor
和ZstdDecompressor
类。用于一次性(解)压缩的
compress()
和decompress()
函数。用于训练和管理 Zstandard 字典的
train_dict()
和finalize_dict()
函数以及ZstdDict
类。用于设置高级(解)压缩参数的
CompressionParameter
、DecompressionParameter
和Strategy
类。
异常¶
- exception compression.zstd.ZstdError¶
当压缩或解压缩过程中,或在初始化(解)压缩器状态时发生错误,会引发此异常。
读写压缩文件¶
- compression.zstd.open(file, /, mode='rb', *, level=None, options=None, zstd_dict=None, encoding=None, errors=None, newline=None)¶
以二进制或文本模式打开一个 Zstandard 压缩文件,返回一个 文件对象。
file 参数可以是一个文件名(以
str
、bytes
或 类路径 对象的形式给出),在这种情况下,将打开指定的文件;或者它也可以是一个已存在的文件对象,用于读取或写入。mode 参数可以是用于读取的
'rb'
(默认)、用于覆盖写入的'wb'
、用于追加的'ab'
,或用于独占创建的'xb'
。它们也可以分别等价地表示为'r'
、'w'
、'a'
和'x'
。你也可以分别使用'rt'
、'wt'
、'at'
和'xt'
以文本模式打开。读取时,options 参数可以是一个提供高级解压缩参数的字典;有关支持的参数的详细信息,请参见
DecompressionParameter
。zstd_dict 参数是一个ZstdDict
实例,用于解压缩过程。读取时,如果 level 参数不为 None,将引发TypeError
。写入时,options 参数可以是一个提供高级压缩参数的字典;有关支持的参数的详细信息,请参见
CompressionParameter
。level 参数是写入压缩数据时使用的压缩级别。level 和 options 中只能有一个不为 None。zstd_dict 参数是一个ZstdDict
实例,用于压缩过程。在二进制模式下,此函数等同于
ZstdFile
的构造函数:ZstdFile(file, mode, ...)
。在这种情况下,不得提供 encoding、errors 和 newline 参数。在文本模式下,会创建一个
ZstdFile
对象,并将其包装在一个io.TextIOWrapper
实例中,该实例具有指定的编码、错误处理行为和行尾符。
- class compression.zstd.ZstdFile(file, /, mode='rb', *, level=None, options=None, zstd_dict=None)¶
以二进制模式打开一个 Zstandard 压缩文件。
一个
ZstdFile
可以包装一个已经打开的 文件对象,或者直接操作一个指定名称的文件。file 参数指定要包装的文件对象,或者要打开的文件名(作为str
、bytes
或 类路径 对象)。如果包装一个已存在的文件对象,当ZstdFile
关闭时,被包装的文件不会被关闭。mode 参数可以是用于读取的
'rb'
(默认)、用于覆盖写入的'wb'
、用于独占创建的'xb'
,或用于追加的'ab'
。它们也可以分别等价地表示为'r'
、'w'
、'x'
和'a'
。如果 file 是一个文件对象(而不是实际的文件名),模式
'w'
不会截断文件,而是等同于'a'
。读取时,options 参数可以是一个提供高级解压缩参数的字典;有关支持的参数的详细信息,请参见
DecompressionParameter
。zstd_dict 参数是一个ZstdDict
实例,用于解压缩过程。读取时,如果 level 参数不为 None,将引发TypeError
。写入时,options 参数可以是一个提供高级压缩参数的字典;有关支持的参数的详细信息,请参见
CompressionParameter
。level 参数是写入压缩数据时使用的压缩级别。level 和 options 中只能有一个被传入。zstd_dict 参数是一个ZstdDict
实例,用于压缩过程。ZstdFile
支持io.BufferedIOBase
指定的所有成员,除了detach()
和truncate()
。支持迭代和with
语句。还提供以下方法和属性:
- peek(size=-1)¶
返回缓冲的数据而不移动文件位置。除非已到达文件末尾(EOF),否则将至少返回一个字节的数据。返回的确切字节数是未指定的(size 参数被忽略)。
- mode¶
读取时为
'rb'
,写入时为'wb'
。
在内存中压缩和解压缩数据¶
- compression.zstd.compress(data, level=None, options=None, zstd_dict=None)¶
压缩 data(一个 类字节对象),返回压缩后的数据,为一个
bytes
对象。level 参数是一个控制压缩级别的整数。level 是在 options 中设置
CompressionParameter.compression_level
的替代方法。在compression_level
上使用bounds()
来获取可以为 level 传递的值。如果需要高级压缩选项,必须省略 level 参数,并在 options 字典中设置CompressionParameter.compression_level
参数。options 参数是一个包含高级压缩参数的 Python 字典。压缩参数的有效键和值在
CompressionParameter
文档中有详细说明。zstd_dict 参数是
ZstdDict
的一个实例,包含用于提高压缩效率的训练数据。可以使用train_dict()
函数生成 Zstandard 字典。
- compression.zstd.decompress(data, zstd_dict=None, options=None)¶
解压缩 data(一个 类字节对象),返回解压缩后的数据,为一个
bytes
对象。options 参数是一个包含高级解压缩参数的 Python 字典。压缩参数的有效键和值在
DecompressionParameter
文档中有详细说明。zstd_dict 参数是
ZstdDict
的一个实例,包含在压缩过程中使用的训练数据。这必须是压缩时使用的同一个 Zstandard 字典。如果 data 是多个不同压缩帧的拼接,则解压缩所有这些帧,并返回结果的拼接。
- class compression.zstd.ZstdCompressor(level=None, options=None, zstd_dict=None)¶
创建一个压缩器对象,可用于增量压缩数据。
要以更方便的方式压缩单个数据块,请参阅模块级函数
compress()
。level 参数是一个控制压缩级别的整数。level 是在 options 中设置
CompressionParameter.compression_level
的替代方法。在compression_level
上使用bounds()
来获取可以为 level 传递的值。如果需要高级压缩选项,必须省略 level 参数,并在 options 字典中设置CompressionParameter.compression_level
参数。options 参数是一个包含高级压缩参数的 Python 字典。压缩参数的有效键和值在
CompressionParameter
文档中有详细说明。zstd_dict 参数是
ZstdDict
的一个可选实例,包含用于提高压缩效率的训练数据。可以使用train_dict()
函数生成 Zstandard 字典。- compress(data, mode=ZstdCompressor.CONTINUE)¶
压缩 data(一个 类字节对象),如果可能,返回一个包含压缩数据的
bytes
对象,否则返回一个空的bytes
对象。部分 data 可能会被内部缓冲,以供后续调用compress()
和flush()
时使用。返回的数据应与之前任何compress()
调用的输出拼接起来。mode 参数是一个
ZstdCompressor
属性,可以是CONTINUE
、FLUSH_BLOCK
或FLUSH_FRAME
。当所有数据都提供给压缩器后,调用
flush()
方法来完成压缩过程。如果以 mode 设置为FLUSH_FRAME
调用compress()
,则不应调用flush()
,因为它会写入一个新的空帧。
- flush(mode=ZstdCompressor.FLUSH_FRAME)¶
完成压缩过程,返回一个
bytes
对象,其中包含存储在压缩器内部缓冲区中的任何数据。mode 参数是一个
ZstdCompressor
属性,可以是FLUSH_BLOCK
或FLUSH_FRAME
。
- set_pledged_input_size(size)¶
指定将为下一帧提供的未压缩数据量 size。size 将被写入下一帧的帧头中,除非
CompressionParameter.content_size_flag
为False
或0
。大小为0
表示帧为空。如果 size 为None
,帧头将省略帧大小。包含未压缩数据大小的帧在解压缩时需要更少的内存,尤其是在较高压缩级别下。如果
last_mode
不是FLUSH_FRAME
,会引发ValueError
,因为压缩器不在帧的起始位置。如果承诺的大小与提供给compress()
的实际数据大小不匹配,未来对compress()
或flush()
的调用可能会引发ZstdError
,并且最后的数据块可能会丢失。在调用
flush()
或compress()
并将模式设为FLUSH_FRAME
后,除非再次调用set_pledged_input_size()
,否则下一帧的帧头将不包含帧大小。
- CONTINUE¶
收集更多数据进行压缩,可能不会立即生成输出。此模式通过最大化每个块和帧的数据量来优化压缩率。
- FLUSH_BLOCK¶
完成并将一个块写入数据流。目前为止返回的数据可以立即解压缩。过去的数据仍然可以在后续调用
compress()
生成的块中被引用,从而提高压缩效果。
- FLUSH_FRAME¶
完成并写出一个帧。后续提供给
compress()
的数据将被写入一个新帧,并且 不能 引用过去的数据。
- last_mode¶
最后一次传递给
compress()
或flush()
的模式。值可以是CONTINUE
、FLUSH_BLOCK
或FLUSH_FRAME
。初始值为FLUSH_FRAME
,表示压缩器处于新帧的开始。
- class compression.zstd.ZstdDecompressor(zstd_dict=None, options=None)¶
创建一个解压缩器对象,可用于增量解压缩数据。
要以更方便的方式一次性解压缩整个压缩流,请参阅模块级函数
decompress()
。options 参数是一个包含高级解压缩参数的 Python 字典。压缩参数的有效键和值在
DecompressionParameter
文档中有详细说明。zstd_dict 参数是
ZstdDict
的一个实例,包含在压缩过程中使用的训练数据。这必须是压缩时使用的同一个 Zstandard 字典。备注
与
decompress()
函数和ZstdFile
类不同,此类不会透明地处理包含多个压缩帧的输入。要解压缩多帧输入,应使用decompress()
,如果处理 文件对象 则使用ZstdFile
,或者使用多个ZstdDecompressor
实例。- decompress(data, max_length=-1)¶
解压缩 data(一个 类字节对象),返回解压缩后的字节数据。部分 data 可能会被内部缓冲,以供后续调用
decompress()
时使用。返回的数据应与之前任何decompress()
调用的输出拼接起来。如果 max_length 为非负数,则该方法最多返回 max_length 字节的解压缩数据。如果达到此限制并且可以产生更多输出,
needs_input
属性将设置为False
。在这种情况下,下一次调用decompress()
时可以提供 data 为b''
来获取更多输出。如果所有输入数据都已解压缩并返回(因为其小于 max_length 字节,或者因为 max_length 为负数),则
needs_input
属性将设置为True
。试图在帧结束后解压缩数据会引发
ZstdError
。在帧结束后找到的任何数据都将被忽略并保存在unused_data
属性中。
- eof¶
如果已到达流末尾标记,则为
True
。
- unused_data¶
压缩流结束后发现的数据。
在到达流末尾之前,此属性将为
b''
。
- needs_input¶
如果
decompress()
方法在需要新的压缩输入之前可以提供更多解压缩数据,则为False
。
Zstandard 字典¶
- compression.zstd.train_dict(samples, dict_size)¶
训练一个 Zstandard 字典,返回一个
ZstdDict
实例。Zstandard 字典可以更有效地压缩小数据,这些数据传统上由于重复性较少而难以压缩。如果你要压缩多个相似的数据组(例如相似的文件),Zstandard 字典可以显著提高压缩率和速度。samples 参数(一个
bytes
对象的可迭代对象),是用于训练 Zstandard 字典的样本总体。dict_size 参数是一个整数,表示 Zstandard 字典的最大尺寸(以字节为单位)。Zstandard 文档建议绝对最大值不超过 100 KB,但根据数据的不同,最大值通常可以更小。较大的字典通常会减慢压缩速度,但能提高压缩率。较小的字典压缩速度更快,但会降低压缩率。
- compression.zstd.finalize_dict(zstd_dict, /, samples, dict_size, level)¶
一个高级函数,用于将“原始内容”Zstandard 字典转换为常规 Zstandard 字典。“原始内容”字典是一个字节序列,不需要遵循普通 Zstandard 字典的结构。
zstd_dict 参数是一个
ZstdDict
实例,其dict_content
包含原始字典内容。samples 参数(一个
bytes
对象的可迭代对象),包含用于生成 Zstandard 字典的样本数据。dict_size 参数是一个整数,表示 Zstandard 字典的最大尺寸(以字节为单位)。有关最大字典大小的建议,请参见
train_dict()
。level 参数(一个整数)是期望传递给使用此字典的压缩器的压缩级别。字典信息因每个压缩级别而异,因此针对适当的压缩级别进行调整可以使压缩更有效。
- class compression.zstd.ZstdDict(dict_content, /, *, is_raw=False)¶
Zstandard 字典的包装器。字典可用于提高许多小数据块的压缩效果。如果需要从样本数据中训练新字典,请使用
train_dict()
。dict_content 参数(一个 类字节对象)是已经训练好的字典信息。
is_raw 参数是一个布尔值,是一个控制 dict_content 含义的高级参数。
True
表示 dict_content 是一个“原始内容”字典,没有任何格式限制。False
表示 dict_content 是一个普通的 Zstandard 字典,由 Zstandard 函数创建,例如train_dict()
或外部 zstd 命令行工具。当向函数传递一个
ZstdDict
时,可以通过将as_digested_dict
和as_undigested_dict
属性作为zstd_dict
参数传递来控制字典的加载方式,例如compress(data, zstd_dict=zd.as_digested_dict)
。消化字典是在加载 Zstandard 字典时发生的一项耗时操作。当多次调用压缩或解压缩时,传递一个已消化的字典将减少加载字典的开销。压缩时的区别¶ 已消化的字典
未消化的字典
可能会被字典参数覆盖的压缩器高级参数
window_log
,hash_log
,chain_log
,search_log
,min_match
,target_length
,strategy
,enable_long_distance_matching
,ldm_hash_log
,ldm_min_match
,ldm_bucket_size_log
,ldm_hash_rate_log
以及一些非公开参数。None
ZstdDict
内部缓存字典是。当再次使用相同压缩级别加载已消化的字典时速度更快。
否。如果你希望多次加载一个未消化的字典,请考虑重用一个压缩器对象。
如果传递一个不带任何属性的
ZstdDict
,压缩时默认传递一个未消化的字典,解压缩时如果需要则会生成并默认传递一个已消化的字典。- dict_content¶
Zstandard 字典的内容,一个
bytes
对象。它与__init__
方法中的 dict_content 参数相同。它可以与其他程序一起使用,例如zstd
命令行程序。
- dict_id¶
Zstandard 字典的标识符,一个非负整数值。
非零值表示该字典是普通的,由 Zstandard 函数创建并遵循 Zstandard 格式。
0
表示一个“原始内容”字典,没有任何格式限制,供高级用户使用。备注
ZstdDict.dict_id
为0
的含义不同于get_frame_info()
函数的dictionary_id
属性。
- as_digested_dict¶
作为已消化的字典加载。
- as_undigested_dict¶
作为未消化的字典加载。
高级参数控制¶
- class compression.zstd.CompressionParameter¶
一个
IntEnum
,包含可在压缩数据时使用的高级压缩参数键。可以在任何属性上使用
bounds()
方法来获取该参数的有效值。参数是可选的;任何省略的参数将自动选择其值。
获取
compression_level
上下限的示例:lower, upper = CompressionParameter.compression_level.bounds()
将
window_log
设置为最大尺寸的示例:_lower, upper = CompressionParameter.window_log.bounds() options = {CompressionParameter.window_log: upper} compress(b'venezuelan beaver cheese', options=options)
- bounds()¶
返回一个压缩参数的整数边界元组
(lower, upper)
。此方法应在你希望检索其边界的属性上调用。例如,要获取compression_level
的有效值,可以检查CompressionParameter.compression_level.bounds()
的结果。上下限都是包含性的。
- compression_level¶
一种高级方式,用于设置影响数据压缩速度和压缩率的其他压缩参数。
常规压缩级别大于
0
。大于20
的值被认为是“超”压缩,并且比其他级别需要更多内存。负值可用于以较差的压缩率换取更快的压缩速度。将级别设置为零将使用
COMPRESSION_LEVEL_DEFAULT
。
- window_log¶
压缩器在压缩数据时可以使用的最大允许反向引用距离,表示为2的幂,即
1 << window_log
字节。此参数极大地影响压缩的内存使用。更高的值需要更多内存,但能获得更好的压缩值。值为零会导致该值被自动选择。
- hash_log¶
初始探测表的大小,表示为2的幂。最终的内存使用量为
1 << (hash_log+2)
字节。对于 <=dfast
的策略,较大的表能提高压缩率;对于 >dfast
的策略,能提高压缩速度。值为零会导致该值被自动选择。
- chain_log¶
多探测搜索表的大小,表示为2的幂。最终的内存使用量为
1 << (chain_log+2)
字节。较大的表能带来更好但更慢的压缩效果。此参数对fast
策略无效。在使用dfast
策略时仍然有用,此时它定义了一个次级探测表。值为零会导致该值被自动选择。
- min_match¶
搜索匹配的最小尺寸。较大的值会提高压缩和解压缩速度,但会降低压缩率。请注意,Zstandard 仍然可以找到更小尺寸的匹配,它只是调整其搜索算法以寻找此尺寸及更大的匹配。对于所有 <
btopt
的策略,有效最小值为4
;对于所有 >fast
的策略,有效最大值为6
。值为零会导致该值被自动选择。
- target_length¶
此字段的影响取决于所选的
Strategy
。对于策略
btopt
、btultra
和btultra2
,该值是被认为“足够好”以停止搜索的匹配长度。较大的值会使压缩率更好,但压缩速度更慢。对于策略
fast
,它是匹配采样的距离。较大的值会使压缩更快,但压缩率更差。值为零会导致该值被自动选择。
- enable_long_distance_matching¶
长距离匹配可用于通过在更远距离处找到大型匹配来提高大输入的压缩效果。它会增加内存使用量和窗口大小。
True
或1
启用长距离匹配,而False
或0
禁用它。启用此参数会增加默认的
window_log
至 128 MiB,除非明确设置为不同值。如果window_log
>= 128 MiB 且压缩策略 >=btopt
(压缩级别 16+),则默认启用此设置。
- ldm_hash_log¶
长距离匹配表的大小,表示为2的幂。较大的值会增加内存使用量和压缩率,但会降低压缩速度。
值为零会导致该值被自动选择。
- ldm_min_match¶
长距离匹配器的最小匹配尺寸。过大或过小的值通常会降低压缩率。
值为零会导致该值被自动选择。
- ldm_bucket_size_log¶
长距离匹配器(long distance matcher)哈希表中用于解决冲突的每个桶(bucket)大小的对数值。值越大,冲突解决能力越强,但会降低压缩速度。
值为零会导致该值被自动选择。
- ldm_hash_rate_log¶
向长距离匹配器哈希表中插入/查找条目的频率。值越大,压缩速度越快。与默认值偏离过大可能会导致压缩率下降。
值为零会导致该值被自动选择。
- content_size_flag¶
在压缩前已知待压缩数据大小时,将其写入 Zstandard 帧头。
此标志仅在以下情况下生效:
调用
compress()
进行一次性压缩。在单次
ZstdCompressor.compress()
调用中,以ZstdCompressor.FLUSH_FRAME
模式提供帧内所有待压缩数据。在对当前帧进行任何
ZstdCompressor.compress()
调用之前,先调用ZstdCompressor.set_pledged_input_size()
并提供将要提供给压缩器的确切数据量。必须为每个新帧调用ZstdCompressor.set_pledged_input_size()
。
所有其他压缩调用可能不会将大小信息写入帧头。
True
或1
启用内容大小标志,而False
或0
则禁用它。
- checksum_flag¶
在每个帧的末尾写入一个四字节的校验和,该校验和使用 XXHash64 算法计算未压缩内容的哈希值。Zstandard 的解压代码会验证此校验和。如果不匹配,则会引发
ZstdError
异常。True
或1
启用校验和生成,而False
或0
则禁用它。
- nb_workers¶
选择要生成的并行压缩线程数。当
nb_workers
> 0 时,启用多线程压缩。值为1
表示“单线程的多线程模式”。更多的线程可以提高速度,但也会增加内存使用量并轻微降低压缩率。值为零则禁用多线程。
- job_size¶
一个压缩作业的大小,以字节为单位。该值仅在
nb_workers
>= 1 时强制执行。每个压缩作业都是并行完成的,因此该值可以间接影响活动线程的数量。值为零会导致该值被自动选择。
- overlap_log¶
设置从先前作业(线程)中重新加载多少数据,以供新作业在压缩期间通过后向查找窗口(look behind window)使用。此值仅在
nb_workers
>= 1 时使用。可接受的值范围为 0 到 9。0 表示动态设置重叠量
1 表示不重叠
9 表示使用前一个作业的完整窗口大小
每增加一,重叠大小减半/加倍。“8”表示
window_size/2
的重叠,“7”表示window_size/4
的重叠,以此类推。
- class compression.zstd.DecompressionParameter¶
一个
IntEnum
,包含解压数据时可使用的高级解压参数键。参数是可选的;任何省略的参数将自动选择其值。可以在任何属性上使用
bounds()
方法来获取该参数的有效值范围。将
window_log_max
设置为最大值的示例data = compress(b'Some very long buffer of bytes...') _lower, upper = DecompressionParameter.window_log_max.bounds() options = {DecompressionParameter.window_log_max: upper} decompress(data, options=options)
- bounds()¶
返回一个解压参数的整数边界元组
(lower, upper)
。应在你希望检索其边界的属性上调用此方法。上下限都是包含性的。
- window_log_max¶
解压期间使用的窗口最大尺寸的以 2 为底的对数。这对于限制解压数据时使用的内存量很有用。较大的最大窗口尺寸可带来更快的解压速度。
值为零会导致该值被自动选择。
杂项¶
- compression.zstd.get_frame_info(frame_buffer)¶
检索一个包含 Zstandard 帧元数据的
FrameInfo
对象。帧包含与其所持有的压缩数据相关的元数据。
- class compression.zstd.FrameInfo¶
与 Zstandard 帧相关的元数据。
- decompressed_size¶
帧解压后内容的大小。
- dictionary_id¶
一个整数,表示解压该帧所需的 Zstandard 字典 ID。
0
表示字典 ID 未记录在帧头中。这可能意味着不需要 Zstandard 字典,或者所需字典的 ID 没有被记录。
- compression.zstd.COMPRESSION_LEVEL_DEFAULT¶
Zstandard 的默认压缩级别:
3
。
- compression.zstd.zstd_version_info¶
运行时 zstd 库的版本号,为一个整数元组 (主版本号, 次版本号, 修订号)。
示例¶
读取压缩文件
from compression import zstd
with zstd.open("file.zst") as f:
file_content = f.read()
创建压缩文件
from compression import zstd
data = b"Insert Data Here"
with zstd.open("file.zst", "w") as f:
f.write(data)
在内存中压缩数据
from compression import zstd
data_in = b"Insert Data Here"
data_out = zstd.compress(data_in)
增量压缩
from compression import zstd
comp = zstd.ZstdCompressor()
out1 = comp.compress(b"Some data\n")
out2 = comp.compress(b"Another piece of data\n")
out3 = comp.compress(b"Even more data\n")
out4 = comp.flush()
# Concatenate all the partial results:
result = b"".join([out1, out2, out3, out4])
将压缩数据写入已打开的文件
from compression import zstd
with open("myfile", "wb") as f:
f.write(b"This data will not be compressed\n")
with zstd.open(f, "w") as zstf:
zstf.write(b"This *will* be compressed\n")
f.write(b"Not compressed\n")
使用压缩参数创建压缩文件
from compression import zstd
options = {
zstd.CompressionParameter.checksum_flag: 1
}
with zstd.open("file.zst", "w", options=options) as f:
f.write(b"Mind if I squeeze in?")