【问题标题】:Add file to tar archive without saving it first将文件添加到 tar 存档而不先保存
【发布时间】:2016-06-01 11:43:35
【问题描述】:

是否可以直接在 tar 存档中创建文件?
上下文:我有一种方法可以将某种内容创建为字符串。我想将此内容保存为 tar 存档中的文件。我必须创建一个 tmpfile 还是有可能直接在 tar 存档中创建一个文件。

def save_files_to_tar(tarname):
    archive = tarfile.open(tarname, mode='w')
    for _ in range(some_number):
        content = get_content()
        # HERE add content to tar

【问题讨论】:

  • 因为我不需要 tar.gz 文件,所以这篇文章不适用
  • 我不认为这是重复的,因为重点是避免创建文件只是为了“移动”到 tar 存档中。我在“思考”中第二个@pacholik 这在import tarfile 之后显然不可能,因为(从文档中引用)“tar 存档是一系列块。存档成员(存储文件)由后面的标题块组成通过数据块。”还略读 API 显示没有任何地方,模块接受某种内存块 / 变量以将其作为成员直接放入存档中。但正如@Ronan 建议的那样,您可以通过 StingIO(甚至 cStringIO?)创建一个类似对象的文件。

标签: python python-3.x tar


【解决方案1】:

我认为你应该使用 StringIO,来创建一个像内存对象这样的文件,并使用 tarInfo 来描述一个假文件,就像这样:

import StringIO
import tarfile

archive = tarfile.open(tarname, mode='w')
for _ in range(some_number):
    content = get_content()
    s = StringIO.StringIO()
    s.write(content)
    s.seek(0)
    tarinfo = tarfile.TarInfo(name="my filename")
    tarinfo.size = len(s.buf)
    archive.addfile(tarinfo=tarinfo, fileobj=s)

archive.close()

希望这会有所帮助。

【讨论】:

  • 当然,您需要将大部分代码放在 save_files_to_tar 函数中。
  • 我可以建议也提供cStringio,因为它可能与性能相关,当一个人想要备用临时文件(除了优雅)?
  • 没错,cStringIO 具有完全相同的用法以获得更好的性能。只要您不需要自定义行为,就应该像@Dilettant 所说的那样使用cStringIO。
  • 我猜,在 Python 3 中它应该类似于 s = io.StringIO()tarinfo.size = len(s.getvalue())archive.addfile(tarinfo=tarinfo, fileobj=io.BytesIO(s.getvalue().encode('utf-8')))
  • 对于那些寻找图像等效代码的人:im = PIL.Image.fromarray(some_array) s = BytesIO() s.write(im.tobytes()) s.seek(0) tarinfo = tarfile.TarInfo(name = "imagename" + ".jpg") tarinfo.size = len(s.getvalue()) tarfile.addfile(tarinfo=tarinfo, fileobj=BytesIO(s.getvalue())) (我不知道)不知道怎么把评论更漂亮,见谅。)
【解决方案2】:

使用上下文管理器兼容 Python 2 和 3 的解决方案:

from __future__ import unicode_literals

import tarfile
import time
from contextlib import closing
from io import BytesIO

message = 'Lorem ipsum dolor sit amet.'
filename = 'test.txt'

with tarfile.open('test.tar', 'w') as tf:
    with closing(BytesIO(message.encode())) as fobj:
        tarinfo = tarfile.TarInfo(filename)
        tarinfo.size = len(fobj.getvalue())
        tarinfo.mtime = time.time()
        tf.addfile(tarinfo, fileobj=fobj)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 2018-11-17
    • 2012-04-03
    • 1970-01-01
    相关资源
    最近更新 更多