2009-04-11 53 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