解压缩在Python

问题描述:

从存储器流BZ2我有CSV数据bz2压缩的数据的块在存储器解压缩在Python

compressed = load_from_network_service(...) 

我想迭代解压缩线的流。

for line in bz2_decompress_stream(compressed): 
    ... 

这样的功能是否存在?

原则上,我可以写入到磁盘,然后使用bz2.BZ2File,这似乎只需要消耗一个文件名

with open('tmp', 'w') as f: 
    f.write(compressed) 
with bz2.BZ2File('tmp') as f: 
    for line in f: 
     ... 

读但是,对于我目前的应用程序的磁盘I/O是一种优质的,所以这是痛苦。

推测bz2.BZ2Decompressor对象在这里可能会有所帮助。我的经验是我给它压缩的数据,它给了我整个解压缩的结果;它似乎并不流畅。也许这是我的数据的限制?

+0

“文件名”只是误导,你也可以给它一个文件对象。从doc:“如果filename是一个str或bytes对象,请直接打开指定的文件,否则filename应该是一个文件对象,它将用于读取或写入压缩数据。” –

有两个截然不同的问题:

  1. 没有写入磁盘

为了解决2,你是对的,你可以使用bz2.BZ2Compressor。但到1的解决方案....完全取决于究竟你的第一线

compressed = load_from_network_service(...)

真的返回。如果compressed是一个字符串,那么你可以做的事情不多:你必须等到你全部检索完毕后再解压。相反,如果例如它是一个增量“装” StringIO,那么你可以这样做(未经测试):

decompressed = '' 
while True: 
    compressed_chunk = compressed.read(100) 
    # Can be empty (even before the stream is exhausted): 
    decompressed_chunk = decompressor.decompress(data) 
    if decompressed_chunk: 
     decompressed += decompressed_chunk 
     new_lines = decompressed.splitlines() 
     decompressed = new_lines[-1] 
     for line in new_lines[:-1]: 
      do_something(line) 
    if len(chunk) < 100: 
     # Reached EOF 
     break 
+0

我收到一个完整的压缩字符串。我想传输解压过程,即使在存储器中有完整的原始输入时,解压过程仍然很有价值。这听起来像我应该手动将数据流式传输到解压缩器,并且它会处理我的数据尾部。 – MRocklin

+0

是的,然后我的解决方案就足够了,然后''compressed = StringIO(压缩)'''。 –