解压缩在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
对象在这里可能会有所帮助。我的经验是我给它压缩的数据,它给了我整个解压缩的结果;它似乎并不流畅。也许这是我的数据的限制?
有两个截然不同的问题:
- 流
- 没有写入磁盘
为了解决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
我收到一个完整的压缩字符串。我想传输解压过程,即使在存储器中有完整的原始输入时,解压过程仍然很有价值。这听起来像我应该手动将数据流式传输到解压缩器,并且它会处理我的数据尾部。 – MRocklin
是的,然后我的解决方案就足够了,然后''compressed = StringIO(压缩)'''。 –
“文件名”只是误导,你也可以给它一个文件对象。从doc:“如果filename是一个str或bytes对象,请直接打开指定的文件,否则filename应该是一个文件对象,它将用于读取或写入压缩数据。” –