bz2 --- 對 bzip2 壓縮算法的支持?

源代碼: Lib/bz2.py


此模塊提供了使用 bzip2 壓縮算法壓縮和解壓數據的一套完整的接口。

bz2 模塊包含:

文件壓縮和解壓?

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

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

BZ2File 的構造函數類(lèi)似,filename 參數可以是一個(gè)實(shí)際的文件名(strbytes 對象),或是已有的可供讀取或寫(xiě)入的文件對象。

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

compresslevel 參數是 1 到 9 的整數,和 BZ2File 的構造函數一樣。

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

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

3.3 新版功能.

在 3.4 版更改: 添加了 'x' (單獨創(chuàng )建) 模式。

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

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

用二進(jìn)制模式打開(kāi) bzip2 壓縮文件。

如果 filename 是一個(gè) strbytes 對象,則打開(kāi)名稱(chēng)對應的文件目錄。 否則的話(huà),filename 應當是一個(gè) file object,它將被用來(lái)讀取或寫(xiě)入壓縮數據。

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

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

如果 mode'w''a',則 compresslevel 可以是 19 之間的整數,用于指定壓縮等級: 1 產(chǎn)生最低壓縮率,而 9 (默認值) 產(chǎn)生最高壓縮率。

如果 mode'r',則輸入文件可以為多個(gè)壓縮流的拼接。

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

BZ2File 還提供了以下方法:

peek([n])?

返回緩沖的數據而不前移文件位置。 至少將返回一個(gè)字節的數據(除非為 EOF)。 實(shí)際返回的字節數不確定。

備注

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

3.3 新版功能.

在 3.1 版更改: 添加了對 with 語(yǔ)句的支持。

在 3.3 版更改: 添加了 fileno(), readable(), seekable(), writable(), read1()readinto() 方法。

在 3.3 版更改: 添加了對 filename 使用 file object 而非實(shí)際文件名的支持。

在 3.3 版更改: 添加了 'a' (append) 模式,以及對讀取多數據流文件的支持。

在 3.4 版更改: 添加了 'x' (單獨創(chuàng )建) 模式。

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

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

在 3.9 版更改: buffering 形參已被移除。 它自 Python 3.0 起即被忽略并棄用。 請傳入一個(gè)打開(kāi)文件對象來(lái)控制文件的打開(kāi)方式。

compresslevel 形參成為僅限關(guān)鍵字參數。

在 3.10 版更改: 這個(gè)類(lèi)在面對多個(gè)同時(shí)讀取器和寫(xiě)入器時(shí)是線(xiàn)程安全的,就如它在 gziplzma 中的等價(jià)類(lèi)所具有的特性一樣。

增量壓縮和解壓?

class bz2.BZ2Compressor(compresslevel=9)?

創(chuàng )建一個(gè)新的壓縮器對象。 此對象可被用來(lái)執行增量數據壓縮。 對于一次性壓縮,請改用 compress() 函數。

如果給定 compresslevel,它必須為 19 之間的整數。 默認值為 9。

compress(data)?

向壓縮器對象提供數據。 在可能的情況下返回一段已壓縮數據,否則返回空字節串。

當你已結束向壓縮器提供數據時(shí),請調用 flush() 方法來(lái)完成壓縮進(jìn)程。

flush()?

結束壓縮進(jìn)程,返回內部緩沖中剩余的壓縮完成的數據。

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

class bz2.BZ2Decompressor?

創(chuàng )建一個(gè)新的解壓縮器對象。 此對象可被用來(lái)執行增量數據解壓縮。 對于一次性解壓縮,請改用 decompress() 函數。

備注

這個(gè)類(lèi)不會(huì )透明地處理包含多個(gè)已壓縮數據流的輸入,這不同于 decompress()BZ2File。 如果你需要通過(guò) BZ2Decompressor 來(lái)解壓縮多個(gè)數據流輸入,你必須為每個(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 形參。

eof?

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

3.3 新版功能.

unused_data?

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

如果在達到數據流末尾之前訪(fǎng)問(wèn)此屬性,其值將為 b''。

needs_input?

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

3.5 新版功能.

一次性壓縮或解壓縮?

bz2.compress(data, compresslevel=9)?

壓縮 data,此參數為一個(gè) 字節類(lèi)對象。

如果給定 compresslevel,它必須為 19 之間的整數。 默認值為 9。

對于增量壓縮,請改用 BZ2Compressor。

bz2.decompress(data)?

解壓縮 data,此參數為一個(gè) 字節類(lèi)對象。

如果 data 是多個(gè)壓縮數據流的拼接,則解壓縮所有數據流。

對于增量解壓縮,請改用 BZ2Decompressor。

在 3.3 版更改: 支持了多數據流的輸入。

用法示例?

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

使用 compress()decompress() 來(lái)顯示往復式的壓縮:

>>>
>>> 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 進(jìn)行增量壓縮:

>>>
>>> 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" 塊數據流)。 隨機數據的壓縮率通常很差,而有序、重復的數據通常會(huì )產(chǎn)生很高的壓縮率。

用二進(jìn)制模式寫(xiě)入和讀取 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