4

我想用 Python 的分层目录结构创建一个 tar 存档,使用字符串作为文件的内容。我读过这个问题,它显示了一种将字符串添加为文件的方法,而不是作为目录。如何在不实际制作目录的情况下将目录动态添加到 tar 存档中?

就像是:

archive.tgz:
    file1.txt
    file2.txt
    dir1/
        file3.txt
        dir2/
            file4.txt
4

3 回答 3

11

扩展链接问题中给出的示例,您可以执行以下操作:

import tarfile
import StringIO
import time

tar = tarfile.TarFile("test.tar", "w")

string = StringIO.StringIO()
string.write("hello")
string.seek(0)

info = tarfile.TarInfo(name='dir')
info.type = tarfile.DIRTYPE
info.mode = 0755
info.mtime = time.time()
tar.addfile(tarinfo=info)

info = tarfile.TarInfo(name='dir/foo')
info.size=len(string.buf)
info.mtime = time.time()
tar.addfile(tarinfo=info, fileobj=string)

tar.close()

请注意mode属性,因为默认值可能不包括目录所有者的执行权限,需要更改目录并获取其内容。

于 2011-12-27T20:35:17.630 回答
2

对有用的已接受答案稍作修改,使其适用于 python 3 和 python 2(并且与 OP 的示例更接近):

from io import BytesIO
import tarfile
import time

# create and open empty tar file
tar = tarfile.open("test.tgz", "w:gz")

# Add a file
file1_contents = BytesIO("hello 1".encode())
finfo1 = tarfile.TarInfo(name='file1.txt')
finfo1.size = len(file1_contents.getvalue())
finfo1.mtime = time.time()
tar.addfile(tarinfo=finfo1, fileobj=file1_contents)

# create directory in the tar file
dinfo = tarfile.TarInfo(name='dir')
dinfo.type = tarfile.DIRTYPE
dinfo.mode = 0o755
dinfo.mtime = time.time()
tar.addfile(tarinfo=dinfo)

# add a file to the new directory in the tar file
file2_contents = BytesIO("hello 2".encode())
finfo2 = tarfile.TarInfo(name='dir/file2.txt')
finfo2.size = len(file2_contents.getvalue())
finfo2.mtime = time.time()
tar.addfile(tarinfo=finfo2, fileobj=file2_contents)

tar.close()

特别是,我按照PEP 3127 -- Integer Literal Support and Syntax更新了八进制语法,切换到BytesIO from io,使用getvalue而不是buf,并使用open而不是TarFile显示压缩输出,如示例中所示。(上下文处理程序用法(with ... as tar:)也适用于 python2 和 python3,但剪切和粘贴不适用于我的 python2 repl,所以我没有切换它。)在 python 2.7.15+ 和 python 3.7.3 上测试。

于 2019-07-05T23:48:36.330 回答
1

查看tar 文件格式似乎可行。每个子目录中的文件都以相对路径名(例如dir1/file3.txt)作为它们的名称。

唯一的诀窍是您必须在进入其中的文件之前定义每个目录(tar不会即时创建必要的子目录)。有一个特殊标志可用于将 tarfile 条目标识为目录,但出于遗留目的,tar也接受名称/以代表目录结尾的文件条目,因此您应该能够dir1/从零添加为文件-长度字符串使用相同的技术。

于 2011-12-27T20:35:10.563 回答