python直接将字符串写入tarfile

时间:2009-04-11 21:41:09

标签: python file file-io tar

有没有办法直接将字符串写入tarfile?从http://docs.python.org/library/tarfile.html看起来只能添加已写入文件系统的文件。

7 个答案:

答案 0 :(得分:32)

我想说通过使用TarInfo e TarFile.addfile将StringIO作为文件对象传递是可能的。

非常粗糙,但有效

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 :(得分:14)

正如Stefano指出的那样,您可以使用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 :(得分:7)

我发现这看起来如何在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

答案 3 :(得分:3)

仅供记录:
StringIO对象具有.len属性 无需寻求(0)和做len(foo.buf)
不需要保持整个字符串来执行len(),或者上帝禁止,自己做会计。

(也许在编写OP时没有。)

答案 4 :(得分:2)

您必须使用TarInfo对象和addfile方法,而不是通常的add方法:

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))

答案 5 :(得分: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)

处理目录和链接需要额外的代码。

答案 6 :(得分:1)

Python 3中的解决方案使用io.BytesIO。确保将TarInfo.size设置为字节的长度,而不是字符串的长度。

给出单个字符串,最简单的解决方案是对其调用.encode()以获取字节。在这个时代,您可能需要使用UTF-8,但是如果收件人希望使用特定的编码,例如ASCII(即无多字节字符),请改用它。

import io
import tarfile

data = 'hello\n'.encode('utf8')
info = tarfile.TarInfo(name='foo.txt')
info.size = len(data)

with tarfile.TarFile('test.tar', 'w') as tar:
    tar.addfile(info, io.BytesIO(data))

如果您确实需要一个可写的 string 缓冲区,类似于@Stefano Borini针对Python 2接受的答案,那么解决方案是在基础{{1}上使用io.TextIOWrapper }缓冲区。

io.BytesIO