有没有一种方法可以直接将字符串写入tar文件?从http://docs.python.org/library/tarfile.html来看,似乎只能添加已经写入文件系统的文件。
有没有一种方法可以直接将字符串写入tar文件?从http://docs.python.org/library/tarfile.html来看,似乎只能添加已经写入文件系统的文件。
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()
正如Stefano所指出的那样,你可以使用TarFile.addfile
和StringIO
。
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
的其他字段(例如mtime
、uname
等)。
我在查找如何在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
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))
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)
data = 'hello\n'.encode()
- gerardw仅作记录:
StringIO对象有一个.len属性。
不需要执行seek(0),也不需要对foo.buf执行len()。
无需将整个字符串保留下来以进行len()操作,更不用说自己进行计算了。
(也许在OP编写时没有这样的属性。)
StringIO
对象没有 len
属性。在 Python 3.8 中,代码 StringIO('foo').len
会引发异常 AttributeError: '_io.StringIO' object has no attribute 'len'
。(也许在回答写作时还没有这个属性。) - Jeyekomonfor 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)
处理目录和链接需要额外的代码。
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))
len()
函数,所以tarfile.copyfileobj
函数将会失败并抛出OSError("end of file reached")
异常。 - luckydonald