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)。在这种情况下,不得提供 *encoding*、*errors* 和 *newline* 参数。

对于文本模式,将创建一个 BZ2File 对象,并将其封装在具有指定编码、错误处理行为和行结束符的 io.TextIOWrapper 实例中。

在 3.3 版本加入。

在 3.4 版本发生变更: 添加了 'x'(独占创建)模式。

在 3.6 版本发生变更: 接受 path-like object

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

返回缓冲数据,而不移动文件位置。至少返回一个字节的数据(除非到达文件末尾)。返回字节的确切数量未指定。

备注

虽然调用 peek() 不会改变 BZ2File 的文件位置,但它可能会改变底层文件对象的位置(例如,如果 BZ2File 是通过将文件对象作为 *filename* 传递来构造的)。

在 3.3 版本加入。

fileno()

返回底层文件的文件描述符。

在 3.3 版本加入。

readable()

返回文件是否以读取模式打开。

在 3.3 版本加入。

seekable()

返回文件是否支持查找。

在 3.3 版本加入。

writable()

返回文件是否以写入模式打开。

在 3.3 版本加入。

read1(size=-1)

读取最多 *size* 个未压缩字节,同时尽量避免从底层流进行多次读取。如果 *size* 为负,则读取缓冲区大小的数据。

如果文件已到达文件末尾,则返回 b''

在 3.3 版本加入。

readinto(b)

将字节读入 *b*。

返回读取的字节数(文件末尾为 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 版本发生变更: 接受 path-like object

在 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*(一个 bytes-like object),以字节形式返回未压缩数据。部分 *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*,一个 bytes-like object

如果给出 *compresslevel*,则它必须是介于 19 之间的整数。默认值为 9

对于增量压缩,请改用 BZ2Compressor

bz2.decompress(data)

解压缩 *data*,一个 bytes-like object

如果 *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