2009-04-11 42 views

回答

28

我會說這是可能的,通過玩TarInfo e TarFile.addfile傳遞一個StringIO作爲fileobject。

很粗糙,但工程

import tarfile 
import StringIO 

tar = tarfile.TarFile("test.tar","w") 

string = StringIO.StringIO() 
string.write("hello") 
string.seek(0) 
info = tarfile.TarInfo(name="foo") 
info.size=len(string.buf) 
tar.addfile(tarinfo=info, fileobj=string) 

tar.close() 
+1

你可以說StringIO.StringIO(「你好」)來代替寫作和尋求。 – misha 2014-03-02 01:13:04

+0

是類似於python3和bytesIO對象的過程嗎? – proteneer 2014-05-18 07:43:15

14

由於斯特凡諾指出的那樣,你可以使用TarFile.addfileStringIO

import tarfile, StringIO 

data = 'hello, world!' 

tarinfo = tarfile.TarInfo('test.txt') 
tarinfo.size = len(data) 

tar = tarfile.open('test.tar', 'a') 
tar.addfile(tarinfo, StringIO.StringIO(data)) 
tar.close() 

你可能要填寫的tarinfo(例如mtimeuname等)以及其他領域。

2

你必須使用TarInfo對象和addfile方法而不是通常的添加方法:

from StringIO import StringIO 
from tarfile import open, TarInfo 

s = "Hello World!" 
ti = TarInfo("test.txt") 
ti.size = len(s) 

tf = open("testtar.tar", "w") 
tf.addfile(ti, StringIO(s)) 
2

在我的情況,我想從現有的tar文件閱讀,一些數據添加到內容,並寫入它到一個新的文件。例如:

for ti in tar_in: 
    buf_in = tar.extractfile(ti) 
    buf_out = io.BytesIO() 
    size = buf_out.write(buf_in.read()) 
    size += buf_out.write(other data) 
    buf_out.seek(0) 
    ti.size = size 
    tar_out.addfile(ti, fileobj=buf_out) 

處理目錄和鏈接需要額外的代碼。

2

僅供備查:
StringIO對象具有.len屬性。
沒有必要尋求(0)和做len(foo.buf)
沒有必要保持整個字符串做len()on,或上帝禁止,自己做會計。

(也許它沒有在OP寫的時間。)

6

我發現這個尋找如何在Django服務於剛剛在內存中的tgz存檔創建的,可能別人會找到我的代碼有用:

import tarfile 
from io import BytesIO 


def serve_file(request): 
    out = BytesIO() 
    tar = tarfile.open(mode = "w:gz", fileobj = out) 
    data = 'lala'.encode('utf-8') 
    file = BytesIO(data) 
    info = tarfile.TarInfo(name="1.txt") 
    info.size = len(data) 
    tar.addfile(tarinfo=info, fileobj=file) 
    tar.close() 

    response = HttpResponse(out.getvalue(), content_type='application/tgz') 
    response['Content-Disposition'] = 'attachment; filename=myfile.tgz' 
    return response 
相關問題