lzma --- 使用 LZMA 算法进行压缩¶
在 3.3 版本加入。
源代码: Lib/lzma.py
此模块提供类和便捷函数,用于使用 LZMA 压缩算法压缩和解压缩数据。还包括一个文件接口,支持 xz 实用工具所使用的 .xz 和旧式 .lzma 文件格式,以及原始压缩流。
此模块提供的接口与 bz2 模块的接口非常相似。请注意 LZMAFile 和 bz2.BZ2File 都*不是*线程安全的,因此如果您需要从多个线程使用单个 LZMAFile 实例,则必须使用锁对其进行保护。
- exception lzma.LZMAError¶
在压缩或解压缩期间,或在初始化压缩器/解压缩器状态时发生错误时,会引发此异常。
读写压缩文件¶
- lzma.open(filename, mode='rb', *, format=None, check=-1, preset=None, filters=None, encoding=None, errors=None, newline=None)¶
以二进制或文本模式打开一个 LZMA 压缩文件,返回一个文件对象。
filename 参数可以是一个实际的文件名(以
str、bytes或类路径对象的形式给出),在这种情况下,将打开指定的文件;或者它也可以是一个已存在的文件对象,用于读取或写入。mode 参数可以是二进制模式的
"r","rb","w","wb","x","xb","a"或"ab"中的任意一个,或文本模式的"rt","wt","xt", 或"at"。默认值为"rb"。当打开文件用于读取时,format 和 filters 参数的含义与
LZMADecompressor的相同。在这种情况下,不应使用 check 和 preset 参数。当打开文件用于写入时,format、check、preset 和 filters 参数的含义与
LZMACompressor的相同。对于二进制模式,此函数等效于
LZMAFile构造函数:LZMAFile(filename, mode, ...)。在这种情况下,不得提供 encoding、errors 和 newline 参数。对于文本模式,会创建一个
LZMAFile对象,并将其包装在一个io.TextIOWrapper实例中,该实例具有指定的编码、错误处理行为和行尾符。在 3.4 版本发生变更: 添加了对
"x"、"xb"和"xt"模式的支持。在 3.6 版本发生变更: 接受 path-like object。
- class lzma.LZMAFile(filename=None, mode='r', *, format=None, check=-1, preset=None, filters=None)¶
以二进制模式打开一个 LZMA 压缩文件。
一个
LZMAFile可以包装一个已经打开的文件对象,或者直接操作一个指定名称的文件。filename 参数指定要包装的文件对象,或要打开的文件的名称(作为str、bytes或类路径对象)。当包装一个已存在的文件对象时,该被包装的文件在LZMAFile关闭时将不会被关闭。mode 参数可以是
"r"用于读取(默认),"w"用于覆盖写入,"x"用于独占创建,或"a"用于追加。这些也可以分别等效地写为"rb"、"wb"、"xb"和"ab"。如果 filename 是一个文件对象(而不是一个实际的文件名),模式
"w"不会截断文件,而是等同于"a"。当打开文件进行读取时,输入文件可以是多个独立压缩流的串联。这些流会被透明地解码为单个逻辑流。
当打开文件用于读取时,format 和 filters 参数的含义与
LZMADecompressor的相同。在这种情况下,不应使用 check 和 preset 参数。当打开文件用于写入时,format、check、preset 和 filters 参数的含义与
LZMACompressor的相同。LZMAFile支持io.BufferedIOBase指定的所有成员,除了detach()和truncate()。支持迭代和with语句。还提供以下方法和属性
- peek(size=-1)¶
返回缓冲的数据,而不移动文件位置。除非已到达文件末尾(EOF),否则将至少返回一个字节的数据。返回的确切字节数是未指定的(size 参数被忽略)。
- mode¶
读取时为
'rb',写入时为'wb'。在 3.13 版本加入。
在 3.4 版本发生变更: 添加了对
"x"和"xb"模式的支持。在 3.5 版本发生变更:
read()方法现在接受None作为参数。在 3.6 版本发生变更: 接受 path-like object。
在内存中压缩和解压缩数据¶
- class lzma.LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None)¶
创建一个压缩器对象,可用于增量压缩数据。
若要更方便地压缩单块数据,请参阅
compress()。format 参数指定应使用的容器格式。可能的值为:
FORMAT_XZ:.xz容器格式。这是默认格式。
FORMAT_ALONE:旧式的.lzma容器格式。这种格式比
.xz更有限——它不支持完整性检查或多个过滤器。
FORMAT_RAW:原始数据流,不使用任何容器格式。此格式说明符不支持完整性检查,并且要求您始终指定一个自定义过滤器链(用于压缩和解压缩)。此外,以此方式压缩的数据不能使用
FORMAT_AUTO解压缩(参见LZMADecompressor)。
check 参数指定要包含在压缩数据中的完整性检查类型。此检查在解压缩时用于确保数据未被损坏。可能的值为:
CHECK_NONE:无完整性检查。这是FORMAT_ALONE和FORMAT_RAW的默认值(也是唯一可接受的值)。CHECK_CRC32:32 位循环冗余校验。CHECK_CRC64:64 位循环冗余校验。这是FORMAT_XZ的默认值。CHECK_SHA256:256 位安全哈希算法。
如果指定的检查不受支持,则会引发
LZMAError。压缩设置可以指定为预设压缩级别(使用 preset 参数),也可以详细指定为自定义过滤器链(使用 filters 参数)。
preset 参数(如果提供)应该是一个介于
0和9(含)之间的整数,可选地与常量PRESET_EXTREME进行“或”运算。如果既未提供 preset 也未提供 filters,则默认行为是使用PRESET_DEFAULT(预设级别6)。更高的预设会产生更小的输出,但会使压缩过程变慢。备注
除了更耗费 CPU 之外,使用更高预设进行压缩还需要更多的内存(并且产生的输出需要更多内存来解压缩)。例如,使用预设
9时,一个LZMACompressor对象的开销可能高达 800 MiB。因此,通常最好坚持使用默认预设。filters 参数(如果提供)应该是一个过滤器链说明符。详情请参见指定自定义过滤器链。
- compress(data)¶
压缩 data(一个
bytes对象),返回一个包含至少部分输入数据的压缩数据的bytes对象。部分 data 可能会被内部缓冲,以供后续调用compress()和flush()时使用。返回的数据应与之前任何compress()调用的输出拼接在一起。
- class lzma.LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)¶
创建一个解压器对象,可用于增量解压数据。
若要更方便地一次性解压缩整个压缩流,请参阅
decompress()。format 参数指定应使用的容器格式。默认值为
FORMAT_AUTO,可以解压缩.xz和.lzma文件。其他可能的值是FORMAT_XZ、FORMAT_ALONE和FORMAT_RAW。memlimit 参数指定解压器可以使用的内存量限制(以字节为单位)。使用此参数时,如果无法在给定的内存限制内解压缩输入,解压缩将失败并引发
LZMAError。filters 参数指定用于创建被解压缩流的过滤器链。如果 format 是
FORMAT_RAW,则此参数是必需的,但不应与其他格式一起使用。有关过滤器链的更多信息,请参见指定自定义过滤器链。备注
与
decompress()和LZMAFile不同,此类不会透明地处理包含多个压缩流的输入。要使用LZMADecompressor解压缩多流输入,您必须为每个流创建一个新的解压缩器。- 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。在到达流末尾后尝试解压缩数据会引发
EOFError。在流末尾之后发现的任何数据都将被忽略并保存在unused_data属性中。在 3.5 版本发生变更: 添加了 max_length 参数。
- check¶
输入流使用的完整性检查的 ID。在解码了足够的输入以确定其使用的完整性检查之前,该值可能为
CHECK_UNKNOWN。
- eof¶
如果已到达流末尾标记,则为
True。
- unused_data¶
压缩流结束后发现的数据。
在到达流的末尾之前,此属性将为
b""。
- needs_input¶
如果
decompress()方法可以在需要新的未压缩输入之前提供更多解压缩数据,则为False。在 3.5 版本加入。
- lzma.compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None)¶
压缩 data(一个
bytes对象),返回压缩后的数据作为一个bytes对象。有关 format、check、preset 和 filters 参数的说明,请参阅上面的
LZMACompressor。
- lzma.decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None)¶
解压缩 data(一个
bytes对象),返回未压缩的数据作为一个bytes对象。如果 data 是多个不同压缩流的串联,则解压缩所有这些流,并返回结果的串联。
有关 format、memlimit 和 filters 参数的说明,请参阅上面的
LZMADecompressor。
杂项¶
- lzma.is_check_supported(check)¶
如果给定的完整性检查在此系统上受支持,则返回
True。CHECK_NONE和CHECK_CRC32总是受支持的。CHECK_CRC64和CHECK_SHA256可能不可用,如果你使用的是使用有限功能集编译的 liblzma 版本。
指定自定义过滤器链¶
过滤器链说明符是一个字典序列,其中每个字典包含单个过滤器的 ID 和选项。每个字典必须包含键 "id",并且可能包含其他键以指定过滤器相关的选项。有效的过滤器 ID 如下:
压缩过滤器
FILTER_LZMA1(用于FORMAT_ALONE)FILTER_LZMA2(用于FORMAT_XZ和FORMAT_RAW)
增量过滤器
FILTER_DELTA
分支-调用-跳转(BCJ)过滤器
FILTER_X86FILTER_IA64FILTER_ARMFILTER_ARMTHUMBFILTER_POWERPCFILTER_SPARC
一个过滤器链最多可以包含 4 个过滤器,并且不能为空。链中的最后一个过滤器必须是压缩过滤器,任何其他过滤器必须是增量或 BCJ 过滤器。
压缩过滤器支持以下选项(作为表示过滤器的字典中的附加条目指定):
preset:用作未明确指定选项的默认值来源的压缩预设。dict_size:字典大小(以字节为单位)。应在 4 KiB 和 1.5 GiB 之间(含)。lc:字面上下文位数。lp:字面位置位数。总和lc + lp必须最多为 4。pb:位置位数;必须最多为 4。mode:MODE_FAST或MODE_NORMAL。nice_len:匹配的“适宜长度”应为何值。应为 273 或更小。mf:使用何种匹配查找器 –MF_HC3、MF_HC4、MF_BT2、MF_BT3或MF_BT4。depth:匹配查找器使用的最大搜索深度。0(默认)表示根据其他过滤器选项自动选择。
增量过滤器存储字节之间的差异,在某些情况下为压缩器产生更具重复性的输入。它支持一个选项 dist。这表示要减去的字节之间的距离。默认值为 1,即取相邻字节之间的差异。
BCJ 过滤器旨在应用于机器代码。它们将代码中的相对分支、调用和跳转转换为使用绝对寻址,目的是增加可被压缩器利用的冗余。这些过滤器支持一个选项 start_offset。这指定了应映射到输入数据开头的地址。默认值为 0。
示例¶
读取压缩文件
import lzma
with lzma.open("file.xz") as f:
file_content = f.read()
创建压缩文件
import lzma
data = b"Insert Data Here"
with lzma.open("file.xz", "w") as f:
f.write(data)
在内存中压缩数据
import lzma
data_in = b"Insert Data Here"
data_out = lzma.compress(data_in)
增量压缩
import lzma
lzc = lzma.LZMACompressor()
out1 = lzc.compress(b"Some data\n")
out2 = lzc.compress(b"Another piece of data\n")
out3 = lzc.compress(b"Even more data\n")
out4 = lzc.flush()
# Concatenate all the partial results:
result = b"".join([out1, out2, out3, out4])
将压缩数据写入已打开的文件
import lzma
with open("file.xz", "wb") as f:
f.write(b"This data will not be compressed\n")
with lzma.open(f, "w") as lzf:
lzf.write(b"This *will* be compressed\n")
f.write(b"Not compressed\n")
使用自定义过滤器链创建压缩文件
import lzma
my_filters = [
{"id": lzma.FILTER_DELTA, "dist": 5},
{"id": lzma.FILTER_LZMA2, "preset": 7 | lzma.PRESET_EXTREME},
]
with lzma.open("file.xz", "w", filters=my_filters) as f:
f.write(b"blah blah blah")