Skip to content

gzip

gzip库提供了简单的接口来帮助用户压缩和解压缩数据。

Tips

该模块的数据压缩功能由zlib模块提供,注意 zlib 不过会添加压缩头,因此两者不能替换使用。

Tips

Python 还提供了lzmabz2两个接口来分别处理 xz 和 bzip2 压缩文件,他们和 gzip 有相同的对外接口

gzip.GzipFile

GzipFile 类构造器,他提供了类似 file-like 对象接口:

Python
class gzip.GzipFile(
  filename=None,    # 文件名
  mode='rb',        # 'r' 'rb' 'a' 'ab' 'w' 'wb' 'x' 'xb'
  compresslevel=9,  # 压缩级别
  fileobj=None,
  mtime=None
):
    pass

Tips

我们通常不使用他,而且使用更为简单的 gzip.open() 接口

gzip.open()

以二进制方式打开一个 gzip 格式的压缩文件,返回一个 file-like 对象(及 GzipFile):

Python
gzip.open(
  filename,
  # 'rb': 解压模式,二进制模式
  # 'rt': 解压模式,文本模式
  # 'wb': 压缩模式,二进制模式
  # 'wt': 压缩模式,文本模式
  # 还有 'ab' 'at' 'xb' 'xt'
  mode='rb',
  compresslevel=9,  # 压缩等级
  encoding=None,    # 文本模式需要指定编码方式
  errors=None,
  newline=None
) -> GzipFile:
    pass

他是我们流式操作的核心,也是我 gzip 使用的主要入口,他支持上下文管理:

Python
import gzip


# 读取压缩文件
with gzip.open('/home/joe/file.txt.gz', 'rb') as f:
    file_content = f.read()

# 创建压缩文件
content = b"Lots of content here"
with gzip.open('/home/joe/file.txt.gz', 'wb') as f:
    f.write(content)

gzip.compress/gzip.decompress

gzip 公开了两个简便的压缩和解压缩方法:

Python
# 压缩 data 返回一个包含已压缩数据的 bytes 对象
gzip.compress(data, compresslevel=9) -> bytes
# 解压缩 data,返回一个包含已解压缩的 bytes 对象
gzip.decompress(data) -> bytes

Notes

它不支持流,如果压缩文件非常大会耗尽内存

Compressor/Decompressor

gzip 并没有提供 Compressor/Decompressor 这样的流式增量压缩和解压缩接口,这是由于历史原因造成的。最初是为了兼容 GNU zip 工具(gzip 和 gunzip)而实现的。因此他的接口操作偏向于文件操作(即 gzip.open() 接口)。而后来他在社区中被广泛使用且接口也很稳定,也就不在增加新的内容了。而后续引入的 lzma 和 bz2 保留了 xxx.open() 接口的同时也添加了 Compressor/Decompressor 接口:

Python
class bz2|lzma.BZ2|LZMACompressor(compresslevel=9):
    """创建一个压缩器对象,可以执行增量压缩"""
    def compress(data):
        """向压缩器对象中添加数据 data,在可能的情况下返回一段已压缩数据,否则返回空字节串。
        当你已结束向压缩器提供数据时,必须调用 flush() 方法来完成压缩进程。
        """
        pass
    def flush():
        """结束压缩进程,返回内部缓冲中剩余的压缩完成的数据。
        调用此方法之后压缩器对象将不可再被使用。
        """
        pass

class bz2|lzma.BZ2|LZMADecompressor:
    """创建一个新的解压缩器对象。 此对象可被用来执行增量数据解压缩"""
    def decompress(data:bytes) -> bytes:
        """ 解压缩 data(一个 bytes-like object),返回字节串形式的解压缩数据。
        某些 data 可以在内部被缓冲,以便用于后续的 decompress() 调用。
        返回的数据应当与之前任何 decompress() 调用的输出进行拼接。
        """
        pass
    eof: bool # 若达到了数据流的末尾标记则为 True。
    unused_data: bytes # 在压缩数据流的末尾之后获取的数据。如果在达到数据流末尾之前访问此属性,其值将为 b''。
    needs_input: bool # 如果在要求新的未解压缩输入之前 decompress() 方法可以提供更多的解压缩数据则为 False。

Tips

尽管 gzip 没有提供这个接口,但是 zlib 提供了 compressobj 和 decompressobj,可以实现类似 Compressor 和 Decompressor 的功能。