VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Python3标准库:zlib GNUzlib压缩

1. zlib GNUzlib压缩

zlib模块为GNU项目zlib压缩库中的很多函数提供了底层接口。

1.1 处理内存中的数据

使用zlib最简单的方法要求把所有将要压缩或解压缩的数据存放在内存中。


	
  1. import zlib
  2. import binascii
  3.  
  4. original_data = b'This is the original text.'
  5. print('Original :', len(original_data), original_data)
  6.  
  7. compressed = zlib.compress(original_data)
  8. print('Compressed :', len(compressed),
  9. binascii.hexlify(compressed))
  10.  
  11. decompressed = zlib.decompress(compressed)
  12. print('Decompressed :', len(decompressed), decompressed)

compress()和decompress()函数都取一个字节序列参数,并且返回一个字节序列。

从前面的例子可以看到,少量数据的压缩版本可能比未压缩的版本还要大。具体的结果取决于输入数据,不过观察小数据集的压缩开销很有意思。 


	
  1. import zlib
  2.  
  3. original_data = b'This is the original text.'
  4.  
  5. template = '{:>15} {:>15}'
  6. print(template.format('len(data)', 'len(compressed)'))
  7. print(template.format('-' * 15, '-' * 15))
  8.  
  9. for i in range(5):
  10. data = original_data * i
  11. compressed = zlib.compress(data)
  12. highlight = '*' if len(data) < len(compressed) else ''
  13. print(template.format(len(data), len(compressed)), highlight)

输出中的*突出显示了哪些行的压缩数据比未压缩版本占用的内存更多。

zlib支持不同的压缩级别,允许在计算成本和空间缩减量之间有所平衡。默认压缩级别zlib.Z_DEFAULT_COMPRESSION为-1,这对应一个硬编码值,表示性能和压缩结果之间的一个折中。当前这对应级别6。


	
  1. import zlib
  2.  
  3. input_data = b'Some repeated text.\n' * 1024
  4. template = '{:>5} {:>5}'
  5.  
  6. print(template.format('Level', 'Size'))
  7. print(template.format('-----', '----'))
  8.  
  9. for i in range(0, 10):
  10. data = zlib.compress(input_data, i)
  11. print(template.format(i, len(data)))

压缩级别为0意味着根本没有压缩。级别9要求的计算最多,同时会生成最小的输出。如下面的例子,对于一个给定的输入,可以多个压缩级别得到的空间缩减量是一样的。

1.2 增量压缩与解压缩

这种内存中的压缩方法有一些缺点,主要是系统需要有足够的内存,可以在内存中同时驻留未压缩和压缩版本,因此这种方法对于真实世界的用例并不实用。另一种方法是使用Compress和Decompress对象以增量方式处理数据,这样就不需要将整个数据集都放在内存中。


	
  1. import zlibimport binascii
  2.  
  3. compressor = zlib.compressobj(1)
  4.  
  5. with open('lorem.txt','rb') as input:
  6. while True:
  7. block = input.read(64)
  8. if not block:
  9. break
  10. compressed = compressor.compress(block)
  11. if compressed:
  12. print('Compressed: {}'.format(
  13. binascii.hexlify(compressed)))
  14. else:
  15. print('buffering...')
  16. remaining = compressor.flush()
  17. print('Flushed: {}'.format(binascii.hexlify(remaining)))

这个例子从一个纯文本文件读取小数据块,并把这个数据集传至compress()。压缩器维护压缩数据的一个内存缓冲区。由于压缩算法依赖于校验和以及最小块大小,所以压缩器每次接收更多输入时可能并没有准备好返回数据。如果它没有准备好一个完整的压缩块,那便会返回一个空字节串。当所有

1.3 混合内容流

在压缩和未压缩数据混合在一起的情况下,还可以使用decompressobj()返回的Decompress类。


	
  1. import zlib
  2.  
  3. lorem = open('lorem.txt','rb').read()
  4. compressed = zlib.compress(lorem)
  5. combined = compressed +lorem
  6.  
  7. decompressor = zlib.decompressobj()
  8. decompressed = decompressor.decompress(combined)
  9.  
  10. decompressed_matches = decompressed ==