lzma ——使用LZMA算法进行压缩

3.3 新版功能.

源代码: Lib/lzma.py


该模块为使用LZMA压缩算法压缩和解压缩数据提供了类和方便的函数。还包括支持 .xz 遗产 .lzma 文件格式 xz 实用程序以及原始压缩流。

该模块提供的接口与 bz2 模块。但是,请注意 LZMAFilenot 线程安全,不像 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压缩文件,返回 file object .

这个 filename 参数可以是实际文件名(作为 strbytespath-like 对象),在这种情况下,将打开命名文件,或者它可以是要读取或写入的现有文件对象。

这个 mode 参数可以是 "r""rb""w""wb""x""xb""a""ab" 对于二进制模式,或 "rt""wt""xt""at" 用于文本模式。默认值为 "rb" .

打开文件进行读取时, 格式过滤器 参数的含义与 LZMADecompressor . 在这种情况下, 检查预设 不应使用参数。

打开文件进行写入时, 格式检查预设过滤器 参数的含义与 LZMACompressor .

对于二进制模式,此函数等价于 LZMAFile 构造函数: LZMAFile(filename, mode, ...) . 在这种情况下, encodingerrorsnewline 不能提供参数。

对于文本模式,A 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 可以封装已打开的 file object 或直接对命名文件进行操作。这个 filename 参数指定要封装的文件对象或要打开的文件的名称(作为 strbytespath-like 对象)。当封装现有文件对象时,当 LZMAFile 关闭。

这个 mode 参数可以是 "r" 对于读取(默认), "w" 对于重写, "x" 为独家创作,或 "a" 供追加。这些可以等价地表示为 "rb""wb""xb""ab" 分别。

如果 filename 是文件对象(而不是实际的文件名),模式为 "w" 不截断文件,而是等价于 "a" .

打开文件进行读取时,输入文件可能是多个单独压缩流的串联。它们被透明地解码为单个逻辑流。

打开文件进行读取时, 格式过滤器 参数的含义与 LZMADecompressor . 在这种情况下, 检查预设 不应使用参数。

打开文件进行写入时, 格式检查预设过滤器 参数的含义与 LZMACompressor .

LZMAFile 支持由指定的所有成员 io.BufferedIOBase ,除了 detach()truncate() . 迭代和 with 支持语句。

还提供了以下方法:

peek(size=- 1)

返回缓冲数据而不前进文件位置。除非达到EOF,否则将返回至少一个字节的数据。返回的确切字节数未指定 size 参数被忽略)。

注解

调用时 peek() 不更改的文件位置 LZMAFile 它可以更改基础文件对象的位置(例如,如果 LZMAFile 是通过传递 filename

在 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_XZ.xz 容器格式。

    这是默认格式。

  • FORMAT_ALONE 遗产 .lzma 容器格式。

    此格式比 .xz --它不支持完整性检查或多个筛选器。

  • FORMAT_RAW :原始数据流,不使用任何容器格式。

    此格式说明符不支持完整性检查,并且要求始终指定自定义筛选器链(用于压缩和解压缩)。此外,以这种方式压缩的数据不能使用 FORMAT_AUTO (见 LZMADecompressor

这个 检查 参数指定要包含在压缩数据中的完整性检查的类型。此检查用于解压缩时,以确保数据未损坏。可能的值是:

  • CHECK_NONE :无完整性检查。这是默认值(也是唯一可接受的值) FORMAT_ALONEFORMAT_RAW .

  • CHECK_CRC32 :32位循环冗余检查。

  • CHECK_CRC64 :64位循环冗余检查。这是默认的 FORMAT_XZ .

  • CHECK_SHA256 :256位安全hash算法。

如果不支持指定的检查,则 LZMAError 提高了。

压缩设置可以指定为预设压缩级别(使用 预设 参数),或者作为自定义过滤链(使用 过滤器 参数)。

这个 预设 参数(如果提供)应为介于 09 (包含),可选或使用常量 PRESET_EXTREME . 如果既不 预设 也不 过滤器 默认行为是使用 PRESET_DEFAULT (预设电平 6 )较高的预设值会产生较小的输出,但会使压缩过程变慢。

注解

除了CPU密集度更高之外,具有更高预设值的压缩还需要更多的内存(并产生需要更多内存来解压缩的输出)。带预置 9 例如, LZMACompressor 对象可以高达800 mib。因此,通常最好使用默认预设。

这个 过滤器 参数(如果提供)应为筛选器链说明符。见 指定自定义筛选链 有关详细信息。

compress(data)

压缩 data (A) bytes 对象),返回 bytes 包含至少部分输入的压缩数据的对象。一些 data 可以在内部缓冲,以便在以后调用 compress()flush() .返回的数据应与之前对 compress() .

flush()

完成压缩过程,返回 bytes 包含压缩程序内部缓冲区中存储的任何数据的对象。

调用此方法后不能使用压缩器。

class lzma.LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)

创建一个解压器对象,该对象可用于增量解压数据。

有关一次对整个压缩流进行解压缩的更方便方法,请参见 decompress() .

这个 格式 参数指定应使用的容器格式。默认值为 FORMAT_AUTO ,可以同时解压缩 .xz.lzma 文件夹。其他可能的值是 FORMAT_XZFORMAT_ALONEFORMAT_RAW .

这个 内存限制 参数指定解压缩程序可以使用的内存量的限制(以字节为单位)。使用此参数时,解压缩将失败,并返回 LZMAError 如果在给定的内存限制内无法解压缩输入。

这个 过滤器 参数指定用于创建要解压缩的流的筛选器链。此参数是必需的,如果 格式FORMAT_RAW ,但不应用于其他格式。见 指定自定义筛选链 有关过滤器链的详细信息。

注解

此类不能透明地处理包含多个压缩流的输入,与 decompress()LZMAFile . 用 LZMADecompressor 必须为每个流创建一个新的解压缩程序。

decompress(data, max_length=- 1)

减压 data (A) bytes-like object ,将未压缩的数据返回为字节。一些 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

False 如果 decompress() 方法可以在需要新的未压缩输入之前提供更多已解压缩的数据。

3.5 新版功能.

lzma.compress(data, format=FORMAT_XZ, check=- 1, preset=None, filters=None)

压缩 data (A) bytes 对象),将压缩数据作为 bytes 对象。

LZMACompressor 上面的说明 格式检查预设过滤器 参数。

lzma.decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None)

减压 data (A) bytes 对象),将未压缩的数据作为 bytes 对象。

如果 data 是多个不同压缩流的串联,解压缩所有这些流,并返回结果的串联。

LZMADecompressor 上面的说明 格式内存限制过滤器 参数。

其他

lzma.is_check_supported(check)

返回 True 如果此系统支持给定的完整性检查。

CHECK_NONECHECK_CRC32 始终支持。 CHECK_CRC64CHECK_SHA256 如果您使用的是 liblzma 这是用有限的功能集编译的。

指定自定义筛选链

过滤链说明符是一系列字典,其中每个字典都包含一个过滤器的ID和选项。每个字典必须包含键 "id" ,并且可以包含其他键来指定依赖于筛选器的选项。有效的筛选器ID如下:

  • 压缩过滤器:
    • FILTER_LZMA1 (供使用) FORMAT_ALONE

    • FILTER_LZMA2 (供使用) FORMAT_XZFORMAT_RAW

  • 三角洲滤波器:
    • FILTER_DELTA

  • 分支调用跳转(BCJ)筛选器:
    • FILTER_X86

    • FILTER_IA64

    • FILTER_ARM

    • FILTER_ARMTHUMB

    • FILTER_POWERPC

    • FILTER_SPARC

一个过滤器链最多可包含4个过滤器,不能为空。链中的最后一个过滤器必须是压缩过滤器,并且任何其他过滤器必须是delta或bcj过滤器。

压缩筛选器支持以下选项(在表示筛选器的字典中指定为其他条目):

  • preset :压缩预设,用作未明确指定选项的默认值源。

  • dict_size :字典大小(字节)。这应该在4 kib和1.5 gib(含)之间。

  • lc :文本上下文位的数目。

  • lp :文字位置位数。和 lc + lp 必须不超过4。

  • pb :位置位数;必须最多为4。

  • mode: MODE_FASTMODE_NORMAL .

  • nice_len :一场比赛的长度应该是多少?这应该是273或更少。

  • mf :要使用的匹配查找工具-- MF_HC3MF_HC4MF_BT2MF_BT3MF_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")