2017-09-19 20 views
0

如何使用python解壓縮內存中的* .bz2文件? bz2文件來自csv文件。如何使用python解壓縮內存中的.tar.bz2

我使用下面的代碼在內存中解壓縮它,它工作,但它帶來了一些骯髒的數據,如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: enter image description here

然後我cd到該文件中,並與tar -cjf res_test.tar.bz2 res_test.csv壓縮,並得到壓縮文件res_test的目錄。 tar.bz2,這個文件可以模擬我將從互聯網獲得的bz2數據,並且我希望在內存中解壓它,而不是先將它緩存到磁盤中,但我得到的是以下數據幷包含太多髒數據: enter image description here

數據仍然存在,但淹沒在噪聲中,是否可以將其解壓縮爲純數據,與原始數據相同,而不是解壓縮它從太多的噪音中提取真實的數據?

回答

2

對於通用bz2解壓縮,可以使用BZ2File類。

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

content應該包含文件的解壓縮內容。

但是,鑑於這是一個tar文件(通常作爲文件目錄提取到磁盤的歸檔文件),可以使用tarfile模塊,並且它具有用於處理bz2的擴展模式標誌。假設目標文件包含一個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使它不切實際從extractfile返回的成員中調用提取文件。第二行簡單地調用extractfile作爲字符串從存檔文件返回'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() 
+0

你好,謝謝你的回答,我已經試過你的方法,但它仍包含在最終的解壓縮數據的噪音太大,我有根據這個測試編輯問題,我只是想知道你能分享一些更多的想法嗎? – buxizhizhoum

+0

@buxizhizhoum我的不好,我不知道你真的在用tarfile工作。 – metatoaster

+0

非常感謝,它的作品!這真是一個好方法。 – buxizhizhoum