如何使用 Python 将文件添加到 tarfile,而不添加目录层次结构?

问题描述 投票:0回答:7

当我在具有文件路径的

add()
对象上调用
tarfile
时,该文件将添加到与目录层次结构关联的 tarball 中。换句话说,如果我解压缩 tar 文件,则会复制原始目录层次结构中的目录。

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

python tar
7个回答
110
投票

使用 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()

62
投票

您可以使用

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

这段代码应该将

/path/to/filename
添加到 TAR 文件中,但会将其提取为
myfilename
:

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

8
投票

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


3
投票

感谢@diabloneo,可以创建目录的选择性 tarball

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"])

1
投票

以下是在不添加文件夹的情况下压缩

folder
中的文件列表的代码示例:

    with tarfile.open(tar_path, 'w') as tar:
        for filename in os.listdir(folder):
            fpath = os.path.join(folder, filename)
            tar.add(fpath, arcname=filename)

0
投票

我一直在寻找类似的问题,但被重定向到此页面,因此我可能会为其他谷歌用户添加此问题。 就我而言,我想要一个 tar 文件,其中仅包含相对文件名,这将递归地工作。所以,一个可压缩的目录

/home/test/data
/home/test/data/content.txt
/home/test/data/files/file.txt

在 zip 中看起来像这样:

content.txt
files/file.txt

默认情况下,python

tarfile
将添加
/
作为额外条目。

我的目标是删除 tar 文件中的前导

/
条目,因为它被视为 ZipSlip 漏洞

当使用具有此类漏洞的 tar 时,您将收到警告

tar: Removing leading `/' from member names

我不确定为什么 python

tarfile
库没有简单的方法来处理这个问题,但我想出了这段代码,它完全符合我的要求:

def package_tar_recursive_without_root_folder(input_dir: str, output_file: str):
    with tarfile.open(output_file, mode='w:gz') as archive:
        for root, dirs, files in os.walk(input_dir):
            for file in files:
                file_path = os.path.join(root, file)
                relative_path = os.path.relpath(file_path, input_dir)
                archive.add(file_path, arcname=relative_path, recursive=False)

-3
投票

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

(1) 创建一个名为

empty
的空目录 (2)
tf.add("empty", arcname=path_you_want_to_add)

这将创建一个名为

path_you_want_to_add
的空目录。

© www.soinside.com 2019 - 2024. All rights reserved.