lzma --- 用 LZMA 算法壓縮?

3.3 新版功能.

源代碼: Lib/lzma.py


此模塊提供了可以壓縮和解壓縮使用 LZMA 壓縮算法的數據的類(lèi)和便攜函數。 其中還包含支持 xz 工具所使用的 .xz 和舊式 .lzma 文件格式的文件接口,以及相應的原始壓縮數據流。

此模塊所提供了接口與 bz2 模塊的非常類(lèi)似。 請注意 LZMAFilebz2.BZ2File不是 線(xiàn)程安全的。,因此如果你需要在多個(gè)線(xiàn)程中使用單個(gè) LZMAFile 實(shí)例,則需要通過(guò)鎖來(lái)保護它。

exception lzma.LZMAError?

當在壓縮或解壓縮期間或是在初始化壓縮器/解壓縮器的狀態(tài)期間發(fā)生錯誤時(shí)此異常會(huì )被引發(fā)。

讀寫(xiě)壓縮文件?

lzma.open(filename, mode='rb', *, format=None, check=- 1, preset=None, filters=None, encoding=None, errors=None, newline=None)?

以二進(jìn)制或文本模式打開(kāi) LZMA 壓縮文件,返回一個(gè) file object。

filename 參數可以是一個(gè)實(shí)際的文件名(以 str, bytes路徑類(lèi) 對象的形式給出),在此情況下會(huì )打開(kāi)指定名稱(chēng)的文件,或者可以是一個(gè)用于讀寫(xiě)的現有文件對象。

mode 參數可以是二進(jìn)制模式的 "r", "rb", "w", "wb", "x", "xb", "a""ab",或者文本模式的 "rt", "wt", "xt""at"。 默認值為 "rb"。

當打開(kāi)一個(gè)文件用于讀取時(shí),formatfilters 參數具有與 LZMADecompressor 的參數相同的含義。 在此情況下,checkpreset 參數不應被使用。

當打開(kāi)一個(gè)文件用于寫(xiě)入的,format, check, presetfilters 參數具有與 LZMACompressor 的參數相同的含義。

對于二進(jìn)制模式,這個(gè)函數等價(jià)于 LZMAFile 構造器: LZMAFile(filename, mode, ...)。 在這種情況下,不可提供 encoding, errorsnewline 參數。

對于文本模式,將會(huì )創(chuàng )建一個(gè) LZMAFile 對象,并將它包裝到一個(gè) io.TextIOWrapper 實(shí)例中,此實(shí)例帶有指定的編碼格式、錯誤處理行為和行結束符。

在 3.4 版更改: 增加了對 "x", "xb""xt" 模式的支持。

在 3.6 版更改: 接受一個(gè) path-like object。

class lzma.LZMAFile(filename=None, mode='r', *, format=None, check=- 1, preset=None, filters=None)?

以二進(jìn)制模式打開(kāi)一個(gè) LZMA 壓縮文件。

LZMAFile 可以包裝在一個(gè)已打開(kāi)的 file object 中,或者是在給定名稱(chēng)的文件上直接操作。 filename 參數指定所包裝的文件對象,或是要打開(kāi)的文件名稱(chēng)(類(lèi)型為 str, bytes路徑類(lèi) 對象)。 如果是包裝現有的文件對象,被包裝的文件在 LZMAFile 被關(guān)閉時(shí)將不會(huì )被關(guān)閉。

mode 參數可以是表示讀取的 "r" (默認值),表示覆寫(xiě)的 "w",表示單獨創(chuàng )建的 "x",或表示添加的 "a"。 這些模式還可以分別以 "rb", "wb", "xb""ab" 的等價(jià)形式給出。

如果 filename 是一個(gè)文件對象(而不是實(shí)際的文件名),則 "w" 模式并不會(huì )截斷文件,而會(huì )等價(jià)于 "a"。

當打開(kāi)一個(gè)文件用于讀取時(shí),輸入文件可以為多個(gè)獨立壓縮流的拼接。 它們會(huì )被作為單個(gè)邏輯流被透明地解碼。

當打開(kāi)一個(gè)文件用于讀取時(shí),formatfilters 參數具有與 LZMADecompressor 的參數相同的含義。 在此情況下,checkpreset 參數不應被使用。

當打開(kāi)一個(gè)文件用于寫(xiě)入的,format, check, presetfilters 參數具有與 LZMACompressor 的參數相同的含義。

LZMAFile 支持 io.BufferedIOBase 所指定的所有成員,但 detach()truncate() 除外。 并支持迭代和 with 語(yǔ)句。

也提供以下方法:

peek(size=- 1)?

返回緩沖的數據而不前移文件位置。 至少將返回一個(gè)字節的數據,除非已經(jīng)到達 EOF。 實(shí)際返回的字節數不確定(會(huì )忽略 size 參數)。

備注

雖然調用 peek() 不會(huì )改變 LZMAFile 的文件位置,但它可能改變下層文件對象的位置(舉例來(lái)說(shuō)如果 LZMAFile 是通過(guò)傳入一個(gè)文件對象作為 filename 的話(huà))。

在 3.4 版更改: 增加了對 "x""xb" 模式的支持。

在 3.5 版更改: read() 方法現在接受 None 作為參數。

在 3.6 版更改: 接受一個(gè) path-like object。

在內存中壓縮和解壓縮數據?

class lzma.LZMACompressor(format=FORMAT_XZ, check=- 1, preset=None, filters=None)?

創(chuàng )建一個(gè)壓縮器對象,此對象可被用來(lái)執行增量壓縮。

壓縮單個(gè)數據塊的更便捷方式請參閱 compress()。

format 參數指定應當使用哪種容器格式。 可能的值有:

  • FORMAT_XZ: .xz 容器格式。

    這是默認格式。

  • FORMAT_ALONE: 傳統的 .lzma 容器格式。

    這種格式相比 .xz 更為受限 -- 它不支持一致性檢查或多重過(guò)濾器。

  • FORMAT_RAW: A raw data stream, not using sequences format.

    這個(gè)格式描述器不支持一致性檢查,并且要求你必須指定一個(gè)自定義的過(guò)濾器鏈(用于壓縮和解壓縮)。 此外,以這種方式壓縮的數據不可使用 FORMAT_AUTO 來(lái)解壓縮 (參見(jiàn) LZMADecompressor)。

check 參數指定要包含在壓縮數據中的一致性檢查類(lèi)型。 這種檢查在解壓縮時(shí)使用,以確保數據沒(méi)有被破壞。 可能的值是:

  • CHECK_NONE: 沒(méi)有一致性檢查。 這是 FORMAT_ALONEFORMAT_RAW 的默認值(也是唯一可接受的值)。

  • CHECK_CRC32: 32 位循環(huán)冗余檢查。

  • CHECK_CRC64: 64 位循環(huán)冗余檢查。 這是 FORMAT_XZ 的默認值。

  • CHECK_SHA256: 256 位安全哈希算法。

如果指定的檢查不受支持,則會(huì )引發(fā) LZMAError。

壓縮設置可被指定為一個(gè)預設的壓縮等級(通過(guò) preset 參數)或以自定義過(guò)濾器鏈來(lái)詳細設置(通過(guò) filters 參數)。

preset 參數(如果提供)應當為一個(gè) 09 (包括邊界) 之間的整數,可以選擇與常數 PRESET_EXTREME 進(jìn)行 OR 運算。 如果 presetfilters 均未給出,則默認行為是使用 PRESET_DEFAULT (預設等級 6)。 更高的預設等級會(huì )產(chǎn)生更小的輸出,但會(huì )使得壓縮過(guò)程更緩慢。

備注

除了更加 CPU 密集,使用更高的預設等級來(lái)壓縮還需要更多的內存(并產(chǎn)生需要更多內存來(lái)解壓縮的輸出)。 例如使用預設等級 9 時(shí),一個(gè) LZMACompressor 對象的開(kāi)銷(xiāo)可以高達 800 MiB。 出于這樣的原因,通常最好是保持使用默認預設等級。

filters 參數(如果提供)應當指定一個(gè)過(guò)濾器鏈。 詳情參見(jiàn) 指定自定義的過(guò)濾器鏈。

compress(data)?

壓縮 data (一個(gè) bytes object),返回包含針對輸入的至少一部分已壓縮數據的 bytes 對象。 一部 data 可能會(huì )被放入內部緩沖區,以便用于后續的 compress()flush() 調用。 返回的數據應當與之前任何 compress() 調用的輸出進(jìn)行拼接。

flush()?

結束壓縮進(jìn)程,返回包含保存在壓縮器的內部緩沖區中的任意數據的 bytes 對象。

調用此方法之后壓縮器將不可再被使用。

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

創(chuàng )建一個(gè)壓縮器對象,此對象可被用來(lái)執行增量解壓縮。

一次性解壓縮整個(gè)壓縮數據流的更便捷方式請參閱 decompress()。

format 參數指定應當被使用的容器格式。 默認值為 FORMAT_AUTO,它可以解壓縮 .xz.lzma 文件。 其他可能的值為 FORMAT_XZ, FORMAT_ALONEFORMAT_RAW。

memlimit 參數指定解壓縮器可以使用的內存上限(字節數)。 當使用此參數時(shí),如果不可能在給定內存上限之內解壓縮輸入數據則解壓縮將失敗并引發(fā) LZMAError。

filters 參數指定用于創(chuàng )建被解壓縮數據流的過(guò)濾器鏈。 此參數在 formatFORMAT_RAW 時(shí)要求提供,但對于其他格式不應使用。 有關(guān)過(guò)濾器鏈的更多信息請參閱 指定自定義的過(guò)濾器鏈。

備注

這個(gè)類(lèi)不會(huì )透明地處理包含多個(gè)已壓縮數據流的輸入,這不同于 decompress()LZMAFile。 要通過(guò) LZMADecompressor 來(lái)解壓縮多個(gè)數據流輸入,你必須為每個(gè)數據流都創(chuàng )建一個(gè)新的解壓縮器。

decompress(data, max_length=- 1)?

解壓縮 data (一個(gè) bytes-like object),返回字節串形式的解壓縮數據。 某些 data 可以在內部被緩沖,以便用于后續的 decompress() 調用。 返回的數據應當與之前任何 decompress() 調用的輸出進(jìn)行拼接。

如果 max_length 為非負數,將返回至多 max_length 個(gè)字節的解壓縮數據。 如果達到此限制并且可以產(chǎn)生后續輸出,則 needs_input 屬性將被設為 False。 在這種情況下,下一次 decompress() 調用提供的 data 可以為 b'' 以獲取更多的輸出。

如果所有輸入數據都已被解壓縮并返回(或是因為它少于 max_length 個(gè)字節,或是因為 max_length 為負數),則 needs_input 屬性將被設為 True。

在到達數據流末尾之后再?lài)L試解壓縮數據會(huì )引發(fā) EOFError。 在數據流末尾之后獲取的任何數據都會(huì )被忽略并存儲至 unused_data 屬性。

在 3.5 版更改: 添加了 max_length 形參。

check?

輸入流使用的一致性檢查的 ID。 這可能為 CHECK_UNKNOWN 直到已解壓了足夠的輸入數據來(lái)確定它所使用的一致性檢查。

eof?

若達到了數據流的末尾標記則為 True。

unused_data?

在壓縮數據流的末尾之后獲取的數據。

在達到數據流末尾之前,這個(gè)值將為 b""。

needs_input?

如果在要求新的未解壓縮輸入之前 decompress() 方法可以提供更多的解壓縮數據則為 False。

3.5 新版功能.

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

壓縮 data (一個(gè) bytes 對象),返回包含壓縮數據的 bytes 對象。

參見(jiàn)上文的 LZMACompressor 了解有關(guān) format, check, presetfilters 參數的說(shuō)明。

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

解壓縮 data (一個(gè) bytes 對象),返回包含解壓縮數據的 bytes 對象。

如果 data 是多個(gè)單獨壓縮數據流的拼接,則解壓縮所有相應數據流,并返回結果的拼接。

參見(jiàn)上文的 LZMADecompressor 了解有關(guān) format, memlimitfilters 參數的說(shuō)明。

雜項?

lzma.is_check_supported(check)?

如果本系統支持給定的一致性檢查則返回 True。

CHECK_NONECHECK_CRC32 總是受支持。 CHECK_CRC64CHECK_SHA256 或許不可用,如果你正在使用基于受限制特性集編譯的 liblzma 版本的話(huà)。

指定自定義的過(guò)濾器鏈?

過(guò)濾器鏈描述符是由字典組成的序列,其中每個(gè)字典包含單個(gè)過(guò)濾器的 ID 和選項。 每個(gè)字典必須包含鍵 "id",并可能包含額外的鍵用來(lái)指定基于過(guò)濾器的選項。 有效的過(guò)濾器 ID 如下:

  • 壓縮過(guò)濾器:
    • FILTER_LZMA1 (配合 FORMAT_ALONE 使用)

    • FILTER_LZMA2 (配合 FORMAT_XZFORMAT_RAW 使用)

  • Delta 過(guò)濾器:
    • FILTER_DELTA

  • Branch-Call-Jump (BCJ) 過(guò)濾器:
    • FILTER_X86

    • FILTER_IA64

    • FILTER_ARM

    • FILTER_ARMTHUMB

    • FILTER_POWERPC

    • FILTER_SPARC

一個(gè)過(guò)濾器鏈最多可由 4 個(gè)過(guò)濾器組成,并且不能為空。 過(guò)濾器鏈中的最后一個(gè)過(guò)濾器必須為壓縮過(guò)濾器,其他過(guò)濾器必須為 Delta 或 BCJ 過(guò)濾器。

壓縮過(guò)濾器支持下列選項(指定為表示過(guò)濾器的字典中的附加條目):

  • preset: 壓縮預設選項,用于作為未顯式指定的選項的默認值的來(lái)源。

  • dict_size: 以字節表示的字典大小。 這應當在 4 KiB 和 1.5 GiB 之間(包含邊界)。

  • lc: 字面值上下文的比特數。

  • lp: 字面值位置的比特數。 總計值 lc + lp 必須不大于 4。

  • pb: 位置的比特數;必須不大于 4。

  • mode: MODE_FASTMODE_NORMAL。

  • nice_len: 對于一個(gè)匹配應當被視為“適宜長(cháng)度”的值。 這應當小于或等于 273。

  • mf: 要使用的匹配查找器 -- MF_HC3, MF_HC4, MF_BT2, MF_BT3MF_BT4。

  • depth: 匹配查找器使用的最大查找深度。 0 (默認值) 表示基于其他過(guò)濾器選項自動(dòng)選擇。

Delta 過(guò)濾器保存字節數據之間的差值,在特定環(huán)境下可產(chǎn)生更具重復性的輸入。 它支持一個(gè) dist 選項,指明要減去的字節之間的差值大小。 默認值為 1,即相鄰字節之間的差值。

BCJ 過(guò)濾器主要作用于機器碼。 它們會(huì )轉換機器碼內的相對分支、調用和跳轉以使用絕對尋址,其目標是提升冗余度以供壓縮器利用。 這些過(guò)濾器支持一個(gè) start_offset 選項,指明應當被映射到輸入數據開(kāi)頭的地址。 默認值為 0。

例子?

在已壓縮的數據中讀取:

import lzma
with lzma.open("file.xz") as f:
    file_content = f.read()

創(chuàng )建一個(gè)壓縮文件:

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

寫(xiě)入已壓縮數據到已打開(kāi)的文件:

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

使用自定義過(guò)濾器鏈創(chuàng )建一個(gè)已壓縮文件:

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