bz2 — 支持 bzip2 压缩

源代码: 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'

BZ2File 构造函数一样,compresslevel 参数是一个介于 1 到 9 之间的整数。

对于二进制模式,此函数等效于 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 压缩文件。

如果 filename 是一个 strbytes 对象,则直接打开指定的文件。否则,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 版新增。

在 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() 可以提供 datab'' 以获取更多输出。

如果所有输入数据都已解压缩并返回(因为这小于 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