Python zlib库 | Python中的zlib是什么
zlib是一个Python库,支持zlib C库,是一种更高级的用于压缩无损压缩算法的通用化库。zlib库被用于无损压缩,意味着在压缩和解压缩之间没有数据损失。
它还提供了跨不同平台的易移植性优势,并且不会扩展数据。
这个库在安全方面扮演着非常重要的角色。许多应用程序需要对任意数据进行压缩和解压缩,比如字符串、文件或结构化的内存内容。
这个库与gzip文件格式/工具非常匹配,gzip是UNIX系统上最流行和有用的压缩应用。
compress()方法
zlib库提供了compress()方法,用于压缩数据字符串。以下是该函数的语法。
compress(data, level=-1)
参数 –
- 数据参数指定要压缩的字节,级别表示一个介于-1到9之间的整数值。级别参数用于定义压缩级别。级别9表示最慢的压缩级别,但它带来最高的压缩级别。值-1是一个默认值,即级别6。级别0表示没有压缩。
让我们来看下面的示例。
示例
import zlib
import binascii
value = 'Welcome to JavaTpoint'
compressed_data = zlib.compress(value, 2)
print('Original data: ' + value)
print('Compressed data: ' + binascii.hexlify(compressed_data))
输出:
Original data: Welcome to JavaTpoint
Compressed data: 785ef348cdc9c95728cf2fca49010018ab043d
如果我们将值2更改为0,则结果如下。
Original data: Welcome to JavaTpoint
Compressed data: 785ef348cdc9c95728cf2fca49010018ab043d
压缩大数据流
zlib库提供 compressobj() 函数来管理大数据流。该方法返回压缩对象。语法如下所示。
语法 –
compressobj(level=-1, method=DEFLATED, wbits=15, memLevel=8, strategy=Z_DEFAULT_STRATEGY[, zdict])
参数 –
- 上述方法接受参数 wbits 来处理窗口大小,并且头部和尾部都包含在输出中。下面是可能的值
值 | 窗口大小的对数 | 输出 |
---|---|---|
+9 到 +15 | 以2为底 | 包含zlib的头部和尾部。 |
+9 到 -15 | 表示wbit的绝对值 | 不包含头部和尾部。 |
+25 到 +31 | 值的低4位。 | 包含头部和尾部的校验和。 |
- method 参数定义了要使用的压缩算法。默认或者可以说是当前可能的算法为 DEFLATED 。
- strategy 参数定义了压缩调优。目前建议仅使用其默认值。
让我们来理解下面的示例
示例
import zlib
import binascii
data = 'Welcome to JavaTpoint'
compress = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, -15)
compressed_data = compress.compress(data)
compressed_data += compress.flush()
print('Original: ' + data)
print('Compressed data: ' + binascii.hexlify(compressed_data))
输出:
Original: Hello world
Compressed data: f348cdc9c95728cf2fca490100
解释 –
我们采用了一个简单的字符串值,它不是一个大数据流,它展示了 compressobj() 函数的工作原理。字符串“欢迎来到JavaTpoint”已经被压缩。通常,在数据流太大或无法容纳到内存中时使用此方法。该方法在较大的应用程序中起到重要作用,我们可以配置压缩并用于串行压缩部分数据。
它在需要压缩的场景中起到重要作用。借助 compress.compress(data) 方法,我们可以压缩和刷新数据块,而无需在内存中累积完整数据。
压缩文件
我们将使用 compression() 方法来压缩文件。语法与前面的示例类似。
在下面的示例中,我们将压缩PNG图像“mountain.png”。
让我们理解以下示例。
示例
import zlib
original_data = open(r'C:\Users\DEVANSH SHARMA\Pictures\Saved Pictures\mountain.png', 'rb').read()
compressed_data = zlib.compress(original_data, zlib.Z_BEST_COMPRESSION)
compress_ratio = (float(len(original_data)) - float(len(compressed_data))) / float(len(original_data))
print('Compressed: %d%%' % (100.0 * compress_ratio))
输出:
Compressed: 10%
在上面的示例中,我们使用了 Z_BEST_COMPRESSION ,这是该算法提供的最佳压缩级别。在下一行中,我们根据压缩数据长度与原始数据之间的比值来计算压缩级别。文件的压缩率为13%,这是如何压缩ASCII字符串或二进制图像数据的方法。
将压缩数据保存到文件中
我们也可以将压缩数据保存到文件中以供进一步使用。在下面的示例中,我们将一些压缩的文本保存到文件中。
示例
import zlib
my_data = 'Welcome to JavaTpoint'
compressed_data = zlib.compress(my_data, 2)
f = open('outfile.txt', 'w')
f.write(compressed_data)
f.close()
当我们运行上面的程序时,它会压缩给定的字符串并将压缩的数据保存到一个名为”output.txt”的文件中。
解压缩
解压缩也是应用程序的一个重要方面。zlib库提供了decompress()方法。以下是其语法。
语法:
decompress(data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)
参数 –
- data 参数是一个字节格式的值。
- wbits 参数用于管理历史缓冲区的大小。可能的缓冲区值如下。
值 | Window大小的对数 | 输入 |
---|---|---|
+8到+15 | 基于2的对数 | 包括zlib头和尾 |
-8到-15 | 表示wbits的绝对值 | 包括无头和尾的原始流 |
+24到+31 = 16 + (8到15) | 表示值的低4位 | 包括gzip头和尾 |
+40到+47 = 32 + (8到15) | 表示值的低4位 | zlib或gzip格式 |
- bufsize参数表示缓冲区大小。这个参数最好的地方在于它不需要是精确的;当需要额外的缓冲区大小时,它的值会自动增加。
让我们来理解以下示例。
示例
import zlib
data = 'Welcome to JavaTpoint'
compressed_data = zlib.compress(data, 2)
decompressed_data = zlib.decompress(compressed_data)
print('Decompressed data: ' + decompressed_data)
输出:
Welcome to JavaTpoint
解压大数据流
在解压大数据流时,由于数据的大小或来源,我们可能会遇到内存管理问题。有可能我们无法完全利用可用的内存来完成特定的任务。因此, decompressobj() 方法允许我们将大的数据流分割成多个块,可以分别进行解压。
语法如下:
语法 –
decompressobj(wbits=15[, zdict])
上述方法返回的是解压缩对象,用于解压缩特定数据。
让我们来理解下面的示例。
示例
import zlib
data = 'Welcome to JavaTpoint'
compress = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, zlib.DEFLATED, +15)
compressed_data = compress.compress(data)
compressed_data += compress.flush()
print('Data before Decompress: ' + data)
print('Data After Decompress: ' + compressed_data)
f = open('compressed.datd', 'w')
f.write(compressed_data)
f.close()
CHUNKSIZE = 1024
data2 = zlib.decompressobj()
my_file = open('compressed.dat', 'rb')
buffer_value = my_file.read(CHUNKSIZE)
# Decompress stream chunks
while buffer_value:
decompressed_data = data2.decompress(buf)
buf = my_file.read(CHUNKSIZE)
decompressed_data += data2.flush()
print('Decompressed data: ' + decompressed_data)
my_file.close()
输出:
Data Before Decompress: Welcome to JavaTpoint
Data After Decompress - #@$%%#@@#s
Decompressed Data: Welcome to JavaTpoint
从文件解压缩数据
正如我们之前讨论的示例一样,我们可以轻松地解压缩文件中的数据。这个示例与之前的示例类似;我们从文件中获取数据,只是这次我们将使用 decompress() 方法。当数据足够小以便轻松地存放在内存中时,此方法非常有用。
让我们来理解以下示例。
示例
import zlib
compressed_data = open('hello.dat', 'rb').read()
decompressed_data = zlib.decompress(compressed_data)
print(decompressed_data)
解释 –
我们已经读取了包含“Welcome to JavaTpoint”的hello.dat文件。然而,文件只包含一个小字符串,因此我们使用了decompress()而不是decompressobj()函数。
结论
Python的zlib库在应用程序需要安全级别的压缩时非常有用。它提供了一系列出色的函数。尽管有许多其他函数可用,但我们讨论了zlib库的一些重要概念。compress()和decompress()方法用于小数据,而compressobj()和decompressobj()方法则可以提供更大的灵活性,支持数据流的压缩/解压缩。