compression.zstd
--- 与 Zstandard 格式兼容的压缩¶
Added in version 3.14.
源代码: Lib/compression/zstd/__init__.py
本模块提供了有关使用 Zstandard (或称 zstd) 压缩算法压缩和解压缩数据的类和函数。 zstd 指南 将 Zstandard 描述为“一种快速的无损压缩算法,针对在 zlib 层级和更高压缩率的实时压缩应用场景。” 本模块还包括了一个支持读写由 zstd 工具创建的 .zst
文件以及原始 zstd 压缩流内容的文件接口。
compression.zstd
模块包含:
用于增量(解)压缩的
ZstdCompressor
和ZstdDecompressor
类。用于一次性压缩和解压的
compress()
和decompress()
函数。train_dict()
和finalize_dict()
函数以及ZstdDict
类用于训练和管理 Zstandard 字典。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 object。
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 object,或者直接操作一个命名文件。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'
用于写入。
- name¶
Zstandard 文件的名称。等同于底层 file object 的
name
属性。
在内存中压缩和解压缩数据¶
- compression.zstd.compress(data, level=None, options=None, zstd_dict=None)¶
压缩 data (一个 bytes-like object),返回压缩后的数据作为一个
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-like object),返回解压缩后的数据作为一个
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-like object),如果可能,返回包含压缩数据的
bytes
对象,否则返回一个空的bytes
对象。data 的一部分可能会在内部缓冲,用于后续调用compress()
和flush()
。返回的数据应与之前任何对compress()
的调用的输出连接起来。mode 参数是
ZstdCompressor
属性,可以是CONTINUE
、FLUSH_BLOCK
或FLUSH_FRAME
。当所有数据都已提供给压缩器时,调用
flush()
方法以完成压缩过程。如果compress()
被调用且 mode 设置为FLUSH_FRAME
,则不应调用flush()
,因为它会写入一个新的空帧。
- flush(mode=ZstdCompressor.FLUSH_FRAME)¶
结束压缩进程,返回包含保存在压缩器的内部缓冲区中的任意数据的
bytes
对象。mode 参数是
ZstdCompressor
属性,可以是FLUSH_BLOCK
或FLUSH_FRAME
。
- set_pledged_input_size(size)¶
指定将为下一个帧提供的未压缩数据 size。除非
CompressionParameter.content_size_flag
为False
或0
,否则 size 将写入下一个帧的帧头。大小为0
表示帧为空。如果 size 为None
,帧头将省略帧大小。包含未压缩数据大小的帧在解压缩时需要更少的内存,尤其是在更高的压缩级别下。如果
last_mode
不是FLUSH_FRAME
,则会引发ValueError
,因为压缩器未处于帧的开始位置。如果承诺的大小与提供给compress()
的实际数据大小不匹配,未来的对compress()
或flush()
的调用可能会引发ZstdError
,并且最后一个数据块可能会丢失。在以
FLUSH_FRAME
模式调用flush()
或compress()
后,除非再次调用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()
,如果处理的是 file object,则使用ZstdFile
类,或者使用多个ZstdDecompressor
实例分别处理。- decompress(data, max_length=-1)¶
解压缩 data (一个 bytes-like object),返回未压缩的数据作为字节。部分 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 参数 (一个 bytes-like object),是已经训练好的字典信息。
is_raw 参数,一个布尔值,是一个高级参数,控制 dict_content 的含义。
True
表示 dict_content 是一个“原始内容”字典,没有任何格式限制。False
表示 dict_content 是一个普通的Zstandard字典,由Zstandard函数例如train_dict()
,或外部 zstd CLI创建。当将一个
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
类会在内部缓存字典数据。是的。在再次加载相同压缩级别的已消化字典时,速度更快。
否。如果希望多次加载未消化字典,考虑重用压缩器对象。
如果传递一个不带任何属性的:class:!ZstdDict,则在压缩时默认传递未消化字典,在解压缩时如果需要会生成并默认传递已消化字典。
- dict_content¶
Zstandard字典的内容,一个
bytes
对象。它与__init__
方法中的 dict_content 参数相同。它可以与其他程序一起使用,例如zstd
CLI程序。
- 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¶
压缩器在压缩数据时可以使用的最大允许后向引用距离,表示为二的幂,
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¶
长距离匹配表的尺寸,以二的幂表示。较大的值会增加内存使用和压缩率,但会降低压缩速度。
值为零会导致自动选择该值。
- ldm_min_match¶
长距离匹配器的最小匹配大小。过大或过小的值通常会降低压缩率。
值为零会导致自动选择该值。
- ldm_bucket_size_log¶
长距离匹配器哈希表中每个桶的日志大小,用于冲突解决。较大的值会改善冲突解决,但会降低压缩速度。
值为零会导致自动选择该值。
- 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¶
设置压缩过程中,新任务可从先前任务(线程)重新加载多少数据供后向参考窗口使用。该参数仅在
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'一些非常长的字节缓冲区...') _lower, upper = DecompressionParameter.window_log_max.bounds() options = {DecompressionParameter.window_log_max: upper} decompress(data, options=options)
- bounds()¶
返回解压缩参数的整型边界元组
(lower, upper)
。此方法应调用在您希望检索边界的属性上。下界和上界都是包含在内的。
- window_log_max¶
解压缩期间使用的最大窗口大小的二进制对数。这有助于限制解压缩数据时使用的内存量。较大的最大窗口大小会导致更快的解压缩。
值为零会导致自动选择该值。
杂项¶
- 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 库的版本号,作为整数元组 (major, minor, release)。
例子¶
读取压缩文件:
from compression import zstd
with zstd.open("file.zst") as f:
file_content = f.read()
创建压缩文件:
from compression import zstd
data = b"在此插入数据"
with zstd.open("file.zst", "w") as f:
f.write(data)
在内存中压缩数据:
from compression import zstd
data_in = b"在此插入数据"
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()
# 将所有部分结果拼接起来:
result = b"".join([out1, out2, out3, out4])
写入已压缩数据到一个已打开的文件:
from compression import zstd
with open("myfile", "wb") as f:
f.write(b"该数据将不会被压缩。\n")
with zstd.open(f, "w") as zstf:
zstf.write(b"这 *将会* 被压缩\n")
f.write(b"没有被压缩\n")
使用压缩形参创建一个已压缩文件:
from compression import zstd
options = {
zstd.CompressionParameter.checksum_flag: 1
}
with zstd.open("file.zst", "w", options=options) as f:
f.write(b"请问现在方便插入(操作/请求)吗?")