bz2bzip2 壓縮支援

原始碼: Lib/bz2.py


此模組提供了一個全面的介面,用於使用 bzip2 壓縮演算法壓縮和解壓縮資料。

bz2 模組包含:

檔案(解)壓縮

bz2.open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None)

以二進位制或文字模式開啟 bzip2 壓縮檔案,返回一個 檔案物件

BZ2File 的建構函式一樣,filename 引數可以是實際的檔名(strbytes 物件),或者是要讀取或寫入的現有檔案物件。

mode 引數可以是 'r''rb''w''wb''x''xb''a''ab' (用於二進位制模式),或 'rt''wt''xt''at'(用於文字模式)。預設值為 'rb'

compresslevel 引數是一個介於 1 和 9 之間的整數,與 BZ2File 建構函式相同。

對於二進位制模式,此函式等效於 BZ2File 建構函式:BZ2File(filename, mode, compresslevel=compresslevel)。在這種情況下,不得提供 encodingerrorsnewline 引數。

對於文字模式,將建立一個 BZ2File 物件,並將其包裝在具有指定編碼、錯誤處理行為和行尾符的 io.TextIOWrapper 例項中。

3.3 版本中新增。

在 3.4 版本中更改: 添加了 'x'(獨佔建立)模式。

在 3.6 版本中更改: 接受 路徑類物件

class bz2.BZ2File(filename, mode='r', *, compresslevel=9)

以二進位制模式開啟 bzip2 壓縮檔案。

如果 filenamestrbytes 物件,則直接開啟指定的檔案。否則,filename 應該是用於讀取或寫入壓縮資料的 檔案物件

mode 引數可以是 'r'(用於讀取,預設值)、'w'(用於覆蓋)、'x'(用於獨佔建立)或 'a'(用於追加)。這些可以等效地表示為 'rb''wb''xb''ab'

如果 filename 是檔案物件(而不是實際的檔名),則模式 'w' 不會截斷檔案,而是等效於 'a'

如果 mode'w''a',則 compresslevel 可以是介於 19 之間的整數,用於指定壓縮級別:1 產生的壓縮率最低,而 9 (預設值)產生的壓縮率最高。

如果 mode'r',則輸入檔案可以是多個壓縮流的串聯。

BZ2File 提供了 io.BufferedIOBase 指定的所有成員,但 detach()truncate() 除外。支援迭代和 with 語句。

BZ2File 還提供了以下方法和屬性:

peek([n])

返回緩衝資料,而不推進檔案位置。至少會返回一個位元組的資料(除非已到達 EOF)。返回的確切位元組數是不確定的。

註解

雖然呼叫 peek() 不會更改 BZ2File 的檔案位置,但它可能會更改底層檔案物件的位置(例如,如果 BZ2File 是透過為 filename 傳遞檔案物件而構建的)。

3.3 版本中新增。

fileno()

返回底層檔案的檔案描述符。

3.3 版本中新增。

readable()

返回檔案是否已開啟以供讀取。

3.3 版本中新增。

seekable()

返回檔案是否支援查詢。

3.3 版本中新增。

writable()

返回檔案是否已開啟以供寫入。

3.3 版本中新增。

read1(size=-1)

讀取最多 size 個未壓縮的位元組,同時嘗試避免從底層流進行多次讀取。如果 size 為負數,則讀取最多一個緩衝區的資料。

如果檔案位於 EOF(檔案末尾),則返回 b''

3.3 版本中新增。

readinto(b)

將位元組讀取到 b 中。

返回讀取的位元組數(EOF 返回 0)。

3.3 版本中新增。

mode

讀取時為 'rb',寫入時為 'wb'

在 3.13 版本中新增。

name

bzip2 檔名。等效於底層 name 屬性的 檔案物件

在 3.13 版本中新增。

在 3.1 版本中更改: 添加了對 with 語句的支援。

在 3.3 版本中更改: 添加了對將 filename 作為 檔案物件 而不是實際檔名的支援。

添加了 'a' (追加)模式,以及對讀取多流檔案的支援。

在 3.4 版本中更改: 添加了 'x'(獨佔建立)模式。

在 3.5 版本中更改: read() 方法現在接受 None 的引數。

在 3.6 版本中更改: 接受 路徑類物件

在 3.9 版本中更改: 已刪除 buffering 引數。自 Python 3.0 起,該引數已被忽略且已棄用。傳遞一個開啟的檔案物件來控制檔案的開啟方式。

compresslevel 引數變為僅限關鍵字。

在 3.10 版本中更改: gziplzma 中的等效類一樣,此類在面對多個同時讀取器或寫入器時是執行緒不安全的。

增量(解)壓縮

class bz2.BZ2Compressor(compresslevel=9)

建立一個新的壓縮器物件。此物件可用於增量壓縮資料。對於一次性壓縮,請改用 compress() 函式。

如果給定 compresslevel,則必須是介於 19 之間的整數。預設值為 9

compress(data)

向壓縮器物件提供資料。如果可能,則返回壓縮資料的塊,否則返回一個空的位元組字串。

當您完成向壓縮器提供資料後,請呼叫 flush() 方法以完成壓縮過程。

flush()

完成壓縮過程。返回內部緩衝區中剩餘的壓縮資料。

在此方法被呼叫後,不得使用壓縮器物件。

class bz2.BZ2Decompressor

建立一個新的解壓縮器物件。此物件可用於增量解壓縮資料。對於一次性壓縮,請改用 decompress() 函式。

註解

decompress()BZ2File 不同,此類不透明地處理包含多個壓縮流的輸入。如果您需要使用 BZ2Decompressor 解壓縮多流輸入,則必須為每個流使用新的解壓縮器。

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 引數。

eof

如果已到達流末尾標記,則為 True

3.3 版本中新增。

unused_data

在壓縮流末尾之後找到的資料。

如果此屬性在到達流末尾之前被訪問,則其值將為 b''

needs_input

如果 decompress() 方法可以在需要新的未壓縮輸入之前提供更多解壓縮資料,則為 False

在 3.5 版本中新增。

一次性(解)壓縮

bz2.compress(data, compresslevel=9)

壓縮 data,一個 類位元組物件

如果給定 compresslevel,則必須是介於 19 之間的整數。預設值為 9

對於增量壓縮,請改用 BZ2Compressor

bz2.decompress(data)

解壓縮 data,一個 類位元組物件

如果 data 是多個壓縮流的串聯,則解壓縮所有流。

對於增量解壓縮,請改用 BZ2Decompressor

在 3.3 版本中更改: 添加了對多流輸入的支援。

用法示例

以下是一些 bz2 模組的典型用法示例。

使用 compress()decompress() 演示往返壓縮

>>> import bz2
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus
... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat.
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
>>> c = bz2.compress(data)
>>> len(data) / len(c)  # Data compression ratio
1.513595166163142
>>> d = bz2.decompress(c)
>>> data == d  # Check equality to original object after round-trip
True

使用 BZ2Compressor 進行增量壓縮

>>> import bz2
>>> def gen_data(chunks=10, chunksize=1000):
...     """Yield incremental blocks of chunksize bytes."""
...     for _ in range(chunks):
...         yield b"z" * chunksize
...
>>> comp = bz2.BZ2Compressor()
>>> out = b""
>>> for chunk in gen_data():
...     # Provide data to the compressor object
...     out = out + comp.compress(chunk)
...
>>> # Finish the compression process.  Call this once you have
>>> # finished providing data to the compressor.
>>> out = out + comp.flush()

上面的例子使用了一個非常“非隨機”的資料流(一個 b"z" 塊的流)。隨機資料往往壓縮效果不佳,而有序、重複的資料通常會產生很高的壓縮比。

以二進位制模式寫入和讀取 bzip2 壓縮檔案

>>> import bz2
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus
... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat.
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
>>> with bz2.open("myfile.bz2", "wb") as f:
...     # Write compressed data to file
...     unused = f.write(data)
...
>>> with bz2.open("myfile.bz2", "rb") as f:
...     # Decompress data from file
...     content = f.read()
...
>>> content == data  # Check equality to original object after round-trip
True