lzma使用LZMA算法进行压缩(4)Python数据压缩和存档(必读进阶Python教程)(参考资料)
该模块提供了使用LZMA压缩算法压缩和解压缩数据的类和便捷功能。还包括一个文件接口,支持xz实用程序使用的.xz
旧.lzma
文件格式 以及原始压缩流。
该模块提供的接口与模块的接口非常相似bz2
。但是,请注意,LZMAFile
是不是线程安全的,不像 bz2.BZ2File
,所以如果你需要使用一个单一的LZMAFile
从多个线程情况下,有必要用锁来保护它。
- 异常
lzma.
LZMAError
- 在压缩或解压缩期间或初始化压缩器/解压缩器状态时发生错误时会引发此异常。
读写压缩文件
lzma.
open
(filename,mode =“rb”,*,format = None,check = -1,preset = None,filters = None,encoding = None,errors = None,newline = None )- 以二进制或文本模式打开LZMA压缩文件,返回文件对象。
该文件名参数可以是一个实际的文件名(给定为一个
str
,bytes
或路径状物体),在这种情况下,指定的文件被打开,或者它可以是现有的文件对象从读取或写入。所述模式参数可以是任何的
"r"
,"rb"
,"w"
,"wb"
,"x"
,"xb"
,"a"
或"ab"
二进制模式,或者"rt"
,"wt"
,"xt"
,或"at"
为文本模式。默认是"rb"
。打开文件进行读取时,format和filters参数的含义与
LZMADecompressor
。在这种情况下,不应使用检查 和预设参数。打开文件进行写入时,格式,检查,预设和 过滤器参数具有相同的含义
LZMACompressor
。对于二进制模式,此函数等效于
LZMAFile
构造函数:。在这种情况下,不得提供编码, 错误和换行参数。LZMAFile(filename, mode, ...)
对于文本模式,将
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
可以换一个已经打开的文件对象,或者直接在指定的文件进行操作。的文件名参数指定任一文件对象来包装,或要打开的文件的名称(作为str
,bytes
或路径状物体)。包装现有文件对象时,关闭时不会关闭包装文件LZMAFile
。所述模式参数可以是
"r"
用于读取(默认值),"w"
用于改写,"x"
专用创建,或"a"
为附加。这些可以等价表示为"rb"
,"wb"
,"xb"
和"ab"
分别。如果filename是文件对象(而不是实际文件名),则模式
"w"
不截断文件,而是等效于"a"
。当打开文件进行读取时,输入文件可以是多个单独压缩流的串联。它们被透明地解码为单个逻辑流。
打开文件进行读取时,format和filters参数的含义与
LZMADecompressor
。在这种情况下,不应使用检查 和预设参数。打开文件进行写入时,格式,检查,预设和 过滤器参数具有相同的含义
LZMACompressor
。LZMAFile
支持指定的所有成员io.BufferedIOBase
,除了detach()
和truncate()
。with
支持迭代和语句。还提供了以下方法:
peek
(size = -1 )- 在不提升文件位置的情况下返回缓冲数据。除非已达到EOF,否则将返回至少一个字节的数据。返回的确切字节数未指定(忽略size参数)。
注意
虽然调用
peek()
不会改变文件的位置LZMAFile
,但它可能会改变底层文件对象的位置(例如,如果LZMAFile
是通过传递文件名的文件对象构造的)。
版本3.4中已更改:添加了对
"x"
和"xb"
模式的支持。在版本3.5中更改:该
read()
方法现在接受参数None
。在版本3.6中更改:接受类似路径的对象。
压缩和解压缩内存中的数据
- 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_ALONE
和FORMAT_RAW
。CHECK_CRC32
:32位循环冗余校验。CHECK_CRC64
:64位循环冗余校验。这是默认值FORMAT_XZ
。CHECK_SHA256
:256位安全散列算法。
如果不支持指定的检查,
LZMAError
则引发a。压缩设置可以指定为预设压缩级别(使用预设参数),也可以指定为自定义筛选器链(使用filters参数)。
的预设参数(如果提供的话)应之间的整数
0
和9
-ED OR(含),任选地与恒定PRESET_EXTREME
。如果既未给出预设也未给出过滤器,则默认行为是使用PRESET_DEFAULT
(预设级别6
)。较高的预设会产生较小的输出,但会使压缩过程变慢。注意
除了占用更多CPU之外,使用更高预设的压缩还需要更多内存(并产生需要更多内存才能解压缩的输出)。
9
例如,使用预设,LZMACompressor
对象的开销 可高达800 MiB。因此,通常最好坚持使用默认预设。该过滤器参数(如果提供的话)应当是一种过滤器链说明符。有关详细信息,请参阅指定自定义筛选链
compress
(数据)- 压缩数据(
bytes
对象),返回bytes
包含至少部分输入的压缩数据的对象。一些 数据可以在内部缓冲,以便稍后调用compress()
和使用flush()
。返回的数据应与之前调用的输出连接compress()
。
flush
()- 完成压缩过程,返回
bytes
包含存储在压缩器内部缓冲区中的任何数据的对象。调用此方法后,无法使用压缩器。
-
- class
lzma.
LZMADecompressor
(format = FORMAT_AUTO,memlimit = None,filters = None ) - 创建一个解压缩器对象,可用于逐步解压缩数据。
有关一次解压缩整个压缩流的更方便的方法,请参阅
decompress()
。该格式参数指定要使用的容器格式。默认值是
FORMAT_AUTO
,可以解压缩文件.xz
和.lzma
文件。其他可能的值是FORMAT_XZ
,FORMAT_ALONE
和FORMAT_RAW
。的MEMLIMIT参数指定的内存,该解压缩器可使用量的限制(以字节为单位)。使用此参数时,
LZMAError
如果无法在给定的内存限制内解压缩输入,则解压缩将失败。该过滤器参数指定用于创建被减压的流过滤器链。如果是 格式
FORMAT_RAW
,则必须使用此参数,但不应将其用于其他格式。有关筛选器链的详细信息,请参阅指定自定义筛选器链。注意
与
decompress()
和不同,此类不透明地处理包含多个压缩流的输入LZMAFile
。要使用解压缩多流输入LZMADecompressor
,必须为每个流创建一个新的解压缩器。decompress
(data,max_length = -1 )- 解压缩数据(类似字节的对象),将未压缩的数据作为字节返回。一些数据可以在内部缓冲,以便在以后的调用中使用
decompress()
。返回的数据应与之前调用的输出连接decompress()
。如果max_length是非负的,则返回 解压缩数据的最多max_length个字节。如果达到此限制并且可以生成更多输出,则该
needs_input
属性将设置为False
。在这种情况下,下一个呼叫到decompress()
可以提供数据作为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 )- 压缩数据(
bytes
对象),将压缩数据作为bytes
对象返回 。有关格式,检查, 预设和过滤器参数
LZMACompressor
的说明,请参见上文。
lzma.
decompress
(data,format = FORMAT_AUTO,memlimit = None,filters = None )- 解压缩数据(
bytes
对象),将未压缩的数据作为bytes
对象返回。如果数据是多个不同压缩流的串联,则解压缩所有这些流,并返回结果的串联。
有关格式, memlimit和过滤器参数
LZMADecompressor
的说明,请参见上文。
杂项
lzma.
is_check_supported
(检查)- 如果此系统支持给定的完整性检查,则返回true。
CHECK_NONE
并CHECK_CRC32
始终支持。CHECK_CRC64
并且CHECK_SHA256
如果你正在使用的版本可能不可用liblzma是用有限的功能集编译。
指定自定义过滤器链
过滤器链说明符是一系列字典,其中每个字典包含单个过滤器的ID和选项。每个字典必须包含密钥"id"
,并且可能包含其他密钥以指定依赖于筛选器的选项。有效的过滤器ID如下:
-
- 压缩过滤器:
-
FILTER_LZMA1
(用于FORMAT_ALONE
)FILTER_LZMA2
(与FORMAT_XZ
和一起使用FORMAT_RAW
)
-
- Delta滤镜:
-
FILTER_DELTA
-
- Branch-Call-Jump(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
:文字位置位数。总和必须至多为4。lc + lp
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")