如何使用 python 在内存中解压 .tar.bz2

how to decompress .tar.bz2 in memory with python

如何用python解压内存中的*.bz2文件? bz2文件来自csv文件。

我用下面的代码在内存中解压,可以,但是会带来一些脏数据,比如csv文件的文件名和作者姓名,有没有其他更好的方法来处理它?

#!/usr/bin/python
# -*- coding: utf-8 -*-
import StringIO
import bz2


with open("/app/tmp/res_test.tar.bz2", "rb") as f:
    content = f.read()

    compressedFile = StringIO.StringIO(content)
    decompressedFile = bz2.decompress(compressedFile.buf)
    compressedFile.seek(0)

    with open("/app/tmp/decompress_test", 'w') as outfile:
        outfile.write(decompressedFile)

我找到了this question,它是gzip格式的,但是我的数据是bz2格式,我试着按照里面的说明去做,但是bz2好像不能这样处理。

编辑:

不管@metatoaster的回答还是上面的代码,都会在最终的解压文件中带入更多的脏数据。 例如:我的原始数据附在下面,并且是 csv 格式,名称为 res_test.csv:

然后我cd到文件所在的目录,用tar -cjf res_test.tar.bz2 res_test.csv压缩,得到压缩文件res_test.tar.bz2,这个文件可以模拟我将从中得到的bz2数据互联网,我希望在内存中解压缩它而不先将其缓存到磁盘中,但我得到的是下面的数据并且包含太多脏数据:

数据还在,但淹没在噪音中,是否可以将其解压为与原始数据相同的纯数据,而不是将其解压并从过多的噪音中提取真实数据?

对于通用的bz2解压缩,可以使用BZ2File class。

from bz2 import BZ2File
with BZ2File("/app/tmp/res_test.tar.bz2") as f:
    content = f.read()

content应该是解压后的文件内容

但是,鉴于这是一个 tar 文件(通常作为文件目录提取到磁盘的存档文件),可以使用 tarfile 模块,并且它具有用于处理 bz2 的扩展模式标志。假设target文件中包含一个res_test.csv,可以使用下面的

tf = tarfile.open('/app/tmp/res_test.tar.bz2', 'r:bz2')
csvfile = tf.extractfile('res_test.csv').read()

r:bz2 标志以一种可以向后查找的方式打开 tar 存档,这很重要,因为替代方法 r|bz2 使得调用提取文件变得不切实际来自成员return extractfile。第二行简单地调用 extractfile 到 return 存档文件中 'res_test.csv' 的内容作为字符串。

通常建议使用透明打开模式 ('r:*'),但是,如果使用 gzip 压缩输入 tar 文件,则不会遇到任何失败。

当然,tarfile 模块有一个较低级别的 open 方法,可用于任意流对象。如果文件已经使用 BZ2File 打开,也可以使用

with BZ2File("/app/tmp/res_test.tar.bz2") as f:
    tf = tarfile.open(fileobj=f, mode='r:')
    csvfile = tf.extractfile('res_test.csv').read()