python直接将字符串写入tarfile

gat*_*ado 34 python file-io file tar

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

Ste*_*ini 35

我想说通过使用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()
Run Code Online (Sandbox Code Playgroud)

  • 你可以只说 StringIO.StringIO("hello") 来代替写和求。 (2认同)
  • @proteneer:我相信在python 3中,seek方法给你一个二进制长度,而它在内部使用字符串```len()```函数,这样```tarfile.copyfileobj```函数就会失败` ``提高OSError("文件结束")``` (2认同)

ava*_*kar 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()
Run Code Online (Sandbox Code Playgroud)

你可能也想填补tarinfo(例如mtime,uname等等)的其他领域.


scy*_*gon 9

我发现这看起来如何在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
Run Code Online (Sandbox Code Playgroud)


Tod*_*wen 6

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))
Run Code Online (Sandbox Code Playgroud)

如果您确实需要一个可写字符串缓冲区,类似于 @Stefano Borini 对于 Python 2 接受的答案,那么解决方案是使用io.TextIOWrapper底层io.BytesIO缓冲区。

import io
import tarfile

textIO = io.TextIOWrapper(io.BytesIO(), encoding='utf8')
textIO.write('hello\n')
bytesIO = textIO.detach()
info = tarfile.TarInfo(name='foo.txt')
info.size = bytesIO.tell()

with tarfile.TarFile('test.tar', 'w') as tar:
    bytesIO.seek(0)
    tar.addfile(info, bytesIO)
Run Code Online (Sandbox Code Playgroud)