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 版本中更改: 接受路径型对象。
- 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 版本中更改: 接受路径型对象。
在内存中压缩和解压缩数据¶
- 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
。如果您使用的是使用有限功能集编译的 liblzma 版本,则CHECK_CRC64
和CHECK_SHA256
可能不可用。
指定自定义过滤器链¶
过滤器链说明符是一系列字典,其中每个字典都包含单个过滤器的 ID 和选项。每个字典必须包含键 "id"
,并且可以包含其他键来指定与过滤器相关的选项。有效的过滤器 ID 如下
压缩过滤器
FILTER_LZMA1
(用于FORMAT_ALONE
)FILTER_LZMA2
(用于FORMAT_XZ
和FORMAT_RAW
)
增量过滤器
FILTER_DELTA
分支-调用-跳转 (BCJ) 过滤器
FILTER_X86
FILTER_IA64
FILTER_ARM
FILTER_ARMTHUMB
FILTER_POWERPC
FILTER_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(默认)表示根据其他过滤器选项自动选择。
Delta 过滤器存储字节之间的差异,在某些情况下为压缩器产生更多重复输入。它支持一个选项,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")