如何在不添加目录层次结构的情况下使用 Python 将文件添加到 tarfile?

Posted

技术标签:

【中文标题】如何在不添加目录层次结构的情况下使用 Python 将文件添加到 tarfile?【英文标题】:How can files be added to a tarfile with Python, without adding the directory hierarchy? 【发布时间】:2010-02-10 19:21:54 【问题描述】:

当我在带有文件路径的tarfile 对象上调用add() 时,该文件将添加到具有关联目录层次结构的压缩包中。换句话说,如果我解压缩 tar 文件,原始目录层次结构中的目录就会被复制。

有没有办法简单地添加一个没有目录信息的普通文件,解压缩生成的 tarball 生成一个平面文件列表?

【问题讨论】:

【参考方案1】:

使用 TarFile.add() 方法的 arcname 参数是匹配目标的另一种便捷方式。

示例:您希望将目录 repo/a.git/ 存档到 tar.gz 文件,但您希望存档中的树根以开头a.git/ 但不是 repo/a.git/,你可以这样做:

archive = tarfile.open("a.git.tar.gz", "w|gz")
archive.add("repo/a.git", arcname="a.git")
archive.close()

【讨论】:

这是一种更好的方法,因为如果您尝试添加目录,则接受的答案将不起作用。 arcname ="a.git" 将在存档中创建一个文件夹 a.git。您可以使用arcname ="" 归档repo/a.git 目录中的文件,而无需创建文件夹。【参考方案2】:

您可以使用tarfile.addfile(),在TarInfo对象中,这是第一个参数,您可以指定一个与您添加的文件不同的name

这段代码应该将/path/to/filename 添加到TAR 文件中,但会将其解压缩为myfilename

tar.addfile(tarfile.TarInfo("myfilename.txt"), open("/path/to/filename.txt"))

【讨论】:

另外,它也适用于tar.add()!要添加整个树,但名称不同,只需执行以下操作:tar.add('/path/to/dir/to/add/', arcname='newdirname'),然后 tarfile 将包含一个名为“newdirname”的目录,并且所有内容都保持不变。 如果你想保存没有所有目录结构的文件。做arcname='.' 这个file()函数是什么?如何导入? 由于某种原因,在我的机器中,这只会创建带有空文件的 tar 存档(文件在那里,但为空)。 当我尝试解压缩并提取内容时,使用arcname='.' 给了我一个IsADirectoryError。使用下面@diabloneo 的答案虽然有效。【参考方案3】:

也许您可以在 TarFile.add(name, arcname) 中使用“arcname”参数。它采用文件在存档中的备用名称。

【讨论】:

【参考方案4】:

感谢@diabloneo,功能可以创建目录的选择性压缩包

def compress(output_file="archive.tar.gz", output_dir='', root_dir='.', items=[]):
    """compress dirs.

    KWArgs
    ------
    output_file : str, default ="archive.tar.gz"
    output_dir : str, default = ''
        absolute path to output
    root_dir='.',
        absolute path to input root dir
    items : list
        list of dirs/items relative to root dir

    """
    os.chdir(root_dir)
    with tarfile.open(os.path.join(output_dir, output_file), "w:gz") as tar:
        for item in items:
            tar.add(item, arcname=item)    


>>>root_dir = "/abs/pth/to/dir/"
>>>compress(output_file="archive.tar.gz", output_dir=root_dir, 
            root_dir=root_dir, items=["logs", "output"])

【讨论】:

您应该始终保护 os.chdir 并尝试最终返回旧的工作目录,因为预计库代码不会更改工作目录。【参考方案5】:

如果您想在 tarfile 中添加目录名称而不是其内容,您可以执行以下操作:

(1) 创建一个名为empty 的空目录 (2)tf.add("empty", arcname=path_you_want_to_add)

这会创建一个名为 path_you_want_to_add 的空目录。

【讨论】:

原始帖子要求包含没有目录的文件。你的回答回答了一个不同的问题。请修改您的答案以回答原始帖子的问题。或者将此添加为评论而不是答案。

以上是关于如何在不添加目录层次结构的情况下使用 Python 将文件添加到 tarfile?的主要内容,如果未能解决你的问题,请参考以下文章

C++:在不违反 SRP 的情况下向多态类层次结构添加方法?

如何在不重复导入***名称的情况下构造python包

如何在不将其添加到目录的情况下在多个团队中安装机器人?

如何在不使用 presentViewController 的情况下以模态方式呈现自定义视图?

如何在不使用 python 保留目录的情况下提取文件夹中的所有 .zip 扩展名?

如何在不创建父目录的情况下使用 wget 镜像目录?