Есть ли способ написать строку непосредственно в tarfile? Из http://docs.python.org/library/tarfile.html похоже, что могут быть добавлены только файлы, уже записанные в файловую систему.
Python записывает строку непосредственно в tarfile
Ответ 1
Я бы сказал, что это возможно, играя с 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()
Ответ 2
Как отметил Стефано, вы можете использовать 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
и т.д.).
Ответ 3
Я нашел, что это выглядит так, как служить в 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
Ответ 4
Вы должны использовать объекты 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
В моем случае я хотел прочитать из существующего файла 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
Только для записи:
Объекты StringIO имеют свойство .len.
Нет необходимости искать (0) и делать len (foo.buf)
Не нужно держать всю строку вокруг, чтобы делать len(), или, не дай бог, делать учет самостоятельно.
(Возможно, это не было в то время, когда OP был написан.)