6.10.7 增量编码
目前提供的一些编码(特别是bz2和zlib)在处理数据流时可能会显著改变数据流的长度。对于大的数据集,这些编码采用增量方式可以更好地处理,即一次只处理一个小数据块。IncrementalEncoder/IncrementalDecoder API就是为此而设计的。
import codecs
import sys
from codecs_to_hex import to_hex
text = b'abcdefghijklmnopqrstuvwxyz\n'
repetitions = 50
print('Text length :',len(text))
print('Repetitions :',repetitions)
print('Expected len:',len(text) * repetitions)
# Encode the text several times to build up a
# large amount of data.
encoder = codecs.getincrementalencoder('bz2')()
encoded = []
print()
print('Encoding:',end=' ')
last = repetitions - 1
for i in range(repetitions):
en_c = encoder.encode(text,final=(i == last))
if en_c:
print('\nEncoded : {} bytes'.format(len(en_c)))
encoded.append(en_c)
else:
sys.stdout.write('.')
all_encoded = b''.join(encoded)
print()
print('Total encoded length:',len(all_encoded))
print()
# Decode the byte string one byte at a time.
decoder = codecs.getincrementaldecoder('bz2')()
decoded = []
print('Decoding:',end=' ')
for i,b in enumerate(all_encoded):
final = (i + 1) == len(text)
c = decoder.decode(bytes([b]),final)
if c:
print('\nDecoded : {} characters'.format(len(c)))
print('Decoding:',end=' ')
decoded.append(c)
else:
sys.stdout.write('.')
print()
restored = b''.join(decoded)
print()
print('Total uncompressed length:',len(restored))
每次将数据传递到编码器或解码器时,其内部状态都会更新。状态一致时(按照codec的定义),会返回数据并重置状态。在此之前,encode()或decode()调用并不返回任何数据。传入最后一位数据时,参数final应当被设置为True,这样codec就知道需要刷新输出所有余下的缓冲数据。
运行结果: