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