Python zlib 库的理解

3 Dec 2024 | 6 分钟阅读

zlib 是一个 Python 库,它支持 zlib C 库,zlib C 库是用于无损压缩算法(deflate)的高层泛化。zlib 库用于无损压缩,这意味着在压缩和解压缩之间没有数据丢失。

它还提供了跨不同平台的兼容性优势,并且不会扩展数据。

在安全性方面,此库发挥着非常重要的作用。许多应用程序需要压缩和解压缩任意数据,例如字符串、文件或内存中的结构化内容。

此库与 **gzip 文件格式/工具** 非常匹配,gzip 是类 UNIX 系统上流行且有用的压缩应用程序。

compress() 方法

zlib 库提供了 **compress()** 方法,用于压缩数据字符串。下面是该函数的语法。

参数 -

  • data 参数指定要压缩的字节,level 是一个介于 -1 到 9 之间的整数。level 参数用于定义压缩级别。级别 9 表示速度最慢,但压缩级别最高。值 -1 是默认值,即级别 6。级别 0 不执行压缩。

让我们了解下面的示例。

示例 -

输出

Original data: Welcome to JavaTpoint
Compressed data: 785ef348cdc9c95728cf2fca49010018ab043d

如果我们把值 2 改为 0,结果将如下所示。

压缩大型数据流

zlib 库提供了 **comressobj()** 函数来管理大型数据流。此方法返回一个压缩对象。语法如下。

语法 -

参数 -

  • 上述方法接受 **wbits** 作为参数,它处理窗口大小,并在输出中包含头部和尾部。下面是可能的 wbits 值:
窗口大小对数输出
+9 到 +15以 2 为底包含 zlib 头部和尾部。
+9 到 -15表示 wbit 的绝对值不包含头部和尾部。
+25 到 +31值的低 4 位。包含头部和尾部校验和。
  • method 参数定义了用于压缩的算法。 **DEFLATED** 是默认的,或者说当前可能的算法。
  • strategy 参数定义了压缩调优。目前建议仅使用其默认值。

让我们理解以下示例

示例 -

输出

Original: Hello world
Compressed data: f348cdc9c95728cf2fca490100

解释 -

我们采用了一个简单的字符串值,它不是一个大的数据流,但足以说明 **compressobj()** 函数的工作原理。字符串“Welcome to JavaTpoint”已被压缩。通常,当数据流太大或无法放入内存时,会使用此方法。此方法在较大的应用程序中扮演着重要的角色,在这些应用程序中,我们可以配置压缩,并可以用于按顺序压缩数据的一部分。

它在需要压缩的地方发挥着重要作用。借助 **compress.compress(data)** 方法,我们可以在不将全部数据累积在内存中的情况下,压缩和刷新数据块。

压缩文件

我们将使用 **compression()** 方法来压缩文件。语法与上一个示例类似。

在下面的示例中,我们将压缩 PNG 图像“mountain.png”。

让我们理解下面的例子。

示例 -

输出

Compressed: 10%

在上面的示例中,我们使用了 **Z_BEST_COMPRESSION**,这是该算法能提供的最佳压缩级别。在下一行,我们根据压缩数据长度与原始数据长度的比率计算压缩级别。文件压缩了 13%,这就是压缩 ASCII 字符串或二进制图像数据的方法。

将压缩数据保存到文件

我们还可以将压缩后的数据保存到文件中以供将来使用。在下面的示例中,我们将一些压缩后的文本显示到文件中。

示例 -

作为上述代码片段的结果,给定的字符串被压缩并保存在一个名为“outfile.txt”的文件中。

解压缩

解压缩也是应用程序的一个重要方面。zlib 库提供了 **decompress()** 方法。下面是它的语法。

语法

参数 -

  • data 参数是一个字节格式的值。
  • wbits 参数用于管理历史缓冲区的大小。可能的缓冲区值如下:
窗口大小对数输入
+8 到 +15以 2 为底包含 zlib 头部和尾部
-8 到 -15表示 wbits 的绝对值包含原始流,无头部和尾部
+24 到 +31 = 16 + (8 到 15)表示值的低 4 位包含 gzip 头部和尾部
+40 到 +47 = 32 + (8 到 15)表示值的低 4 位zlib 或 gzip 格式
  • bufsize 参数指示缓冲区大小。关于此参数的最好之处在于,它不需要精确;当需要额外的缓冲区大小时,其值会自动增加。

让我们理解下面的例子。

示例 -

输出

Welcome to JavaTpoint

解压缩大型数据流

在解压缩大型数据流时,我们可能会遇到内存管理问题,这取决于数据的大小或来源。我们可能无法为该特定任务利用所有可用内存。因此,**decompressobj()** 允许我们将大型流分成多个块,可以单独解压缩。

语法如下。

语法 -

上述方法返回一个解压缩对象,用于解压缩特定数据。

让我们理解下面的例子。

示例 -

输出

Data before Decompress: Welcome to JavaTpoint
Compressed Data: b'x\x9c\x0bO\xcdI\xce\xcfMU(\xc9W\xf0J,K\x0c)\xc8\xcf\xcc+\x01\x00U{\x07\xf0'
Decompressed data: Welcome to JavaTpoint

从文件中解压缩数据

正如我们在前面的示例中讨论过的,我们可以轻松地解压缩文件中包含的数据。此示例与前面的示例类似;我们从文件中获取数据,不同之处在于,在本例中,我们将使用 **decompress()** 方法。当数据足够小,可以轻松放入内存时,此方法非常有用。

让我们理解下面的例子。

示例 -

解释 -

我们读取了包含“Welcome to JavaTpoint”的 hello.dat。但是,该文件包含一个小的字符串,因此我们使用了 decompress() 而不是 **decompressobj()** 函数。

结论

当应用程序需要一定安全级别的压缩时,Python zlib 库非常有用。它提供了一系列出色的函数。我们已经讨论了 zlib 库的一些重要概念,尽管还有许多其他函数可用。compress() 和 decompress() 方法用于小数据,而 compressobj() 和 decompressobj() 方法通过支持数据流的压缩/解压缩来提供更大的灵活性。