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")