将文件添加到 tar 存档而不先保存

Posted

技术标签:

【中文标题】将文件添加到 tar 存档而不先保存【英文标题】:Add file to tar archive without saving it first 【发布时间】: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

【问题讨论】:

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

【讨论】:

以上是关于将文件添加到 tar 存档而不先保存的主要内容,如果未能解决你的问题,请参考以下文章

节点:将字符串作为文件添加到 tar 存档中(没有临时文件)

使用 Apache Commons Compress 库以非机器依赖的方式将文件和目录添加到 Tar 存档

在 Perl 脚本中无法将目录添加到存档

HP-UX - 如何在不解压缩的情况下从 tar 存档中读取文本文件?

仅使用 7z 压缩文件而不保留路径

学习Linux tar 命令:最简单也最困难