tarfile ---读取和写入tar存档文件

源代码: Lib/tarfile.py


这个 tarfile 模块使读写tar档案成为可能,包括那些使用gzip、bz2和lzma压缩的档案。使用 zipfile 读写模块 .zip 文件或更高级别的函数 shutil .

一些事实和数字:

  • 读写 gzipbz2lzma 压缩档案(如果相应模块可用)。

  • 对posix.1-1988(USTAR)格式的读/写支持。

  • 对GNU tar格式的读/写支持,包括 长名长链 扩展,只读支持 稀疏的 扩展,包括恢复稀疏文件。

  • 对posix.1-2001(pax)格式的读/写支持。

  • 处理目录、常规文件、硬链接、符号链接、FIFO、字符设备和块设备,并能够获取和恢复文件信息,如时间戳、访问权限和所有者。

在 3.3 版更改: 为添加了支持 lzma 压缩。

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)

返回A TarFile 路径名的对象 name . 有关详细信息 TarFile 对象和允许的关键字参数,请参见 tarfile对象 .

mode 必须是窗体的字符串 'filemode[:compression]' ,默认为 'r' . 以下是模式组合的完整列表:

模式

行动

'r' or 'r:*'

打开进行透明压缩阅读(推荐)。

'r:'

开放阅读,无需压缩。

'r:gz'

打开以使用gzip压缩进行读取。

'r:bz2'

用bzip2压缩打开阅读。

'r:xz'

用LZMA压缩打开阅读。

'x' or 'x:'

只创建一个tarfile而不压缩。养一个 FileExistsError 异常(如果它已经存在)。

'x:gz'

使用gzip压缩创建tarfile。养一个 FileExistsError 异常(如果它已经存在)。

'x:bz2'

使用bzip2压缩创建tarfile。养一个 FileExistsError 异常(如果它已经存在)。

'x:xz'

使用lzma压缩创建tarfile。养一个 FileExistsError 异常(如果它已经存在)。

'a' or 'a:'

打开以附加而不压缩。如果文件不存在,则创建该文件。

'w' or 'w:'

开放进行未压缩的写作。

'w:gz'

打开进行gzip压缩写入。

'w:bz2'

打开进行bzip2压缩写入。

'w:xz'

打开LZMA压缩写入。

注意 'a:gz''a:bz2''a:xz' 不可能。如果 mode 不适合打开某个(压缩)文件进行读取, ReadError 提高了。使用 mode 'r' 为了避免这种情况。如果不支持压缩方法, CompressionError 提高了。

如果 文件对象 是指定的,它用作 file object 以二进制模式打开 name . 应该在0位置。

对于模式 'w:gz''r:gz''w:bz2''r:bz2''x:gz''x:bz2'tarfile.open() 接受关键字参数 压缩能级 (默认) 9 )指定文件的压缩级别。

出于特殊目的,有第二种格式用于 mode'filemode|[compression]' . tarfile.open() 将返回 TarFile 以块流形式处理其数据的对象。不会对文件进行随机查找。如果给出的话, 文件对象 可能是任何具有 read()write() 方法(取决于 mode蟾蜍尺码 指定块大小并默认为 20 * 512 字节。将此变体与例如 sys.stdin Socket file object 或磁带设备。然而,这样的 TarFile 对象被限制为不允许随机访问,请参见 实例 . 当前可能的模式:

模式

行动

'r|*'

打开一个 流动 以透明压缩方式读取的焦油块。

'r|'

打开一个 流动 用于读取的未压缩焦油块。

'r|gz'

打开gzip压缩文件 流动 用于阅读。

'r|bz2'

打开bzip2压缩文件 流动 用于阅读。

'r|xz'

打开压缩的LZMA 流动 用于阅读。

'w|'

打开未压缩的 流动 写作。

'w|gz'

打开gzip压缩文件 流动 写作。

'w|bz2'

打开bzip2压缩文件 流动 写作。

'w|xz'

打开压缩的LZMA 流动 写作。

在 3.5 版更改: 这个 'x' 添加了(独占创建)模式。

在 3.6 版更改: 这个 name 参数接受 path-like object .

class tarfile.TarFile

读写tar档案的课程。不要直接使用此类:使用 tarfile.open() 相反。见 tarfile对象 .

tarfile.is_tarfile(name)

返回 True 如果 name 是tar存档文件,即 tarfile 模块可以读取。 name 可能是 str ,文件或类似文件的对象。

在 3.9 版更改: 支持文件和类似文件的对象。

这个 tarfile 模块定义以下异常:

exception tarfile.TarError

所有的基类 tarfile 例外情况。

exception tarfile.ReadError

在打开tar存档时引发,两者都不能由 tarfile 模块或以某种方式无效。

exception tarfile.CompressionError

在不支持压缩方法或无法正确解码数据时引发。

exception tarfile.StreamError

是针对流式的典型限制而提出的 TarFile 物体。

exception tarfile.ExtractError

被引发为 non-fatal 使用时出错 TarFile.extract() ,但仅当 TarFile.errorlevel == 2 .

exception tarfile.HeaderError

是由 TarInfo.frombuf() 如果它得到的缓冲区无效。

以下常数在模块级可用:

tarfile.ENCODING

默认字符编码: 'utf-8' 在Windows上,返回的值 sys.getfilesystemencoding() 否则。

以下每一个常量都定义了一个tar存档格式, tarfile 模块能够创建。见节 支持的tar格式 有关详细信息。

tarfile.USTAR_FORMAT

posix.1-1988(USTAR)格式。

tarfile.GNU_FORMAT

GNU焦油格式。

tarfile.PAX_FORMAT

posix.1-2001(pax)格式。

tarfile.DEFAULT_FORMAT

用于创建存档的默认格式。这是目前 PAX_FORMAT .

在 3.8 版更改: 新存档的默认格式已更改为 PAX_FORMATGNU_FORMAT .

参见

模块 zipfile

文件 zipfile 标准模块。

归档操作

标准提供的更高级别存档设施的文件 shutil 模块。

GNU tar manual, Basic Tar Format

tar存档文件的文档,包括GNU tar扩展。

tarfile对象

这个 TarFile 对象提供到tar存档的接口。tar存档是一系列块。存档成员(存储的文件)由头块和数据块组成。可以多次将文件存储在tar存档中。每个存档成员由一个 TarInfo 对象,参见 对象信息对象 有关详细信息。

A TarFile 对象可以用作 with 声明。块完成后自动关闭。请注意,如果出现异常情况,将不会完成打开进行写入的存档;只关闭内部使用的文件对象。查看 实例 用于用例的部分。

3.2 新版功能: 增加了对上下文管理协议的支持。

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=0)

以下所有参数都是可选的,可以作为实例属性访问。

name 是存档的路径名。 name 可能是 path-like object . 如果 文件对象 给出。在这种情况下,文件对象的 name 如果属性存在,则使用该属性。

mode 要么是 'r' 要从现有存档中读取, 'a' 要将数据附加到现有文件中, 'w' 创建覆盖现有文件的新文件,或 'x' 仅当新文件不存在时才创建新文件。

如果 文件对象 它用于读取或写入数据。如果可以确定, mode 被覆盖 文件对象 的模式。 文件对象 将从位置0使用。

注解

文件对象 未关闭,当 TarFile 关闭。

格式 控制写入的存档格式。它必须是常数之一 USTAR_FORMATGNU_FORMATPAX_FORMAT 在模块级定义的。读取时,将自动检测格式,即使单个存档中存在不同的格式。

这个 塔尔文 参数可用于替换默认值 TarInfo 用另一个来上课。

如果 撤销引用False ,将符号和硬链接添加到存档。如果是 True ,将目标文件的内容添加到存档。这对不支持符号链接的系统没有影响。

如果 ignore_zerosFalse ,将空块作为存档的结尾。如果是 True ,跳过空(和无效)块,并尝试获取尽可能多的成员。这只对读取连接的或损坏的档案有用。

调试 可以从 0 (无调试消息)最多 3 (所有调试消息)。消息被写入 sys.stderr .

如果 错误级别0 ,使用时忽略所有错误 TarFile.extract() . 然而,当启用调试时,它们在调试输出中显示为错误消息。如果 1 ,所有 致命的 错误被引发为 OSError 例外情况。如果 2 ,所有 non-fatal 错误被引发为 TarError 也有例外。

这个 encodingerrors 参数定义用于读取或写入存档的字符编码,以及如何处理转换错误。默认设置适用于大多数用户。见节 Unicode问题 获取深入的信息。

这个 pax_headers 参数是可选的字符串字典,如果 格式PAX_FORMAT .

在 3.2 版更改: 使用 'surrogateescape' 作为默认的 errors 参数。

在 3.5 版更改: 这个 'x' 添加了(独占创建)模式。

在 3.6 版更改: 这个 name 参数接受 path-like object .

classmethod TarFile.open(...)

备选施工单位。这个 tarfile.open() 函数实际上是这个类方法的快捷方式。

TarFile.getmember(name)

返回A TarInfo 成员的对象 name .如果 name 在档案中找不到, KeyError 提高了。

注解

如果某个成员在存档中出现多次,则其最后一次出现的版本将被假定为最新版本。

TarFile.getmembers()

将存档的成员作为列表返回 TarInfo 物体。列表的顺序与存档中的成员相同。

TarFile.getnames()

将成员作为名称列表返回。它与返回的列表的顺序相同 getmembers() .

TarFile.list(verbose=True, *, members=None)

将目录打印到 sys.stdout .如果 verboseFalse ,只打印成员的姓名。如果是 True ,输出类似于 ls -l 是生产出来的。如果可选 成员 如果给定,则它必须是由返回的列表的子集 getmembers() .

在 3.5 版更改: 增加了 成员 参数。

TarFile.next()

将存档的下一个成员作为 TarInfo 对象时 TarFile 打开阅读。返回 None 如果没有更多可用的。

TarFile.extractall(path='.', members=None, *, numeric_owner=False)

将存档中的所有成员提取到当前工作目录或目录 path . 如果可选 成员 如果给定,则它必须是由返回的列表的子集 getmembers() . 在提取所有成员之后设置目录信息,如所有者、修改时间和权限。这样做是为了解决两个问题:每次在目录中创建文件时,都会重置目录的修改时间。而且,如果一个目录的权限不允许写入,那么将文件提取到该目录将失败。

如果 numeric_ownerTrue ,tarfile中的uid和gid编号用于设置提取文件的所有者/组。否则,将使用tarfile中的命名值。

警告

未经事先检查,不得从不受信任的来源提取档案。文件可能是在 path ,例如,绝对文件名以 "/" 或带有两个点的文件名 ".." .

在 3.5 版更改: 增加了 numeric_owner 参数。

在 3.6 版更改: 这个 path 参数接受 path-like object .

TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False)

使用成员的全名将其从存档中提取到当前工作目录。它的文件信息被尽可能准确地提取出来。 成员 可以是文件名或 TarInfo 对象。可以使用指定其他目录 path . path 可能是 path-like object . 设置文件属性(所有者、mtime、模式),除非 set_attrs 是假的。

如果 numeric_ownerTrue ,tarfile中的uid和gid编号用于设置提取文件的所有者/组。否则,将使用tarfile中的命名值。

注解

这个 extract() 方法不处理几个提取问题。在大多数情况下,您应该考虑使用 extractall() 方法。

警告

参见警告 extractall() .

在 3.2 版更改: 增加了 set_attrs 参数。

在 3.5 版更改: 增加了 numeric_owner 参数。

在 3.6 版更改: 这个 path 参数接受 path-like object .

TarFile.extractfile(member)

从存档中提取成员作为文件对象。 成员 可以是文件名或 TarInfo 对象。如果 成员 是常规文件或链接,则为 io.BufferedReader 对象,则返回。对于所有其他现有成员, None 返回。如果 成员 不会出现在档案中, KeyError 都被养大了。

在 3.3 版更改: 返回一 io.BufferedReader 对象。

TarFile.add(name, arcname=None, recursive=True, *, filter=None)

添加文件 name 归档。 name 可以是任何类型的文件(目录、FIFO、符号链接等)。如果给出的话, 弧名 指定存档中文件的替代名称。默认情况下,目录是递归添加的。这可以通过设置来避免 递归的False . 递归按排序顺序添加条目。如果 滤波器 如果给定,它应该是一个函数, TarInfo 对象参数并返回已更改的 TarInfo 对象。如果它回来了 None 这个 TarInfo 对象将从存档中排除。见 实例 举个例子。

在 3.2 版更改: 增加了 滤波器 参数。

在 3.7 版更改: 递归按排序顺序添加条目。

TarFile.addfile(tarinfo, fileobj=None)

添加 TarInfo 对象 塔尔文 到档案馆。如果 文件对象 它应该是一个 binary filetarinfo.size 从中读取字节并将其添加到存档中。你可以创造 TarInfo 直接或通过使用 gettarinfo() .

TarFile.gettarinfo(name=None, arcname=None, fileobj=None)

创建一个 TarInfo 对象的结果 os.stat() 或现有文件上的等效文件。文件的命名方式为 name 或指定为 file object 文件对象 带有文件描述符。 name 可能是 path-like object . 如果给出的话, 弧名 为存档中的文件指定另一个名称,否则,该名称取自 文件对象name 属性,或 name 参数。名称应为文本字符串。

您可以修改 TarInfo 的属性,然后使用 addfile() . 如果文件对象不是位于文件开头的普通文件对象,则属性如下 size 可能需要修改。这种情况适用于以下对象: GzipFile . 这个 name 也可以修改,在这种情况下 弧名 可能是虚拟字符串。

在 3.6 版更改: 这个 name 参数接受 path-like object .

TarFile.close()

关闭 TarFile . 在写模式下,两个完成的零块被附加到存档中。

TarFile.pax_headers

包含pax全局头的键值对的字典。

对象信息对象

A TarInfo 对象表示 TarFile . 除了存储文件的所有必需属性(如文件类型、大小、时间、权限、所有者等),它还提供了一些确定文件类型的有用方法。它确实 not 包含文件的数据本身。

TarInfo 对象由返回 TarFile 方法 getmember()getmembers()gettarinfo() .

class tarfile.TarInfo(name='')

创建一个 TarInfo 对象。

classmethod TarInfo.frombuf(buf, encoding, errors)

创建并返回 TarInfo 字符串缓冲区中的对象 buf .

引发 HeaderError 如果缓冲区无效。

classmethod TarInfo.fromtarfile(tarfile)

从中读取下一个成员 TarFile 对象 tarfile 把它作为 TarInfo 对象。

TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')

从创建字符串缓冲区 TarInfo 对象。有关参数的信息,请参见 TarFile 类。

在 3.2 版更改: 使用 'surrogateescape' 作为默认的 errors 参数。

A TarInfo 对象具有以下公共数据属性:

TarInfo.name

存档成员的名称。

TarInfo.size

字节大小。

TarInfo.mtime

上次修改时间。

TarInfo.mode

权限位。

TarInfo.type

文件类型。 type 通常是这些常量之一: REGTYPEAREGTYPELNKTYPESYMTYPEDIRTYPEFIFOTYPECONTTYPECHRTYPEBLKTYPEGNUTYPE_SPARSE . 确定A的类型 TarInfo 对象更方便,使用 is*() 方法如下。

TarInfo.linkname

目标文件名的名称,仅存在于 TarInfo 类型对象 LNKTYPESYMTYPE .

TarInfo.uid

最初存储此成员的用户的用户ID。

TarInfo.gid

最初存储此成员的用户的组ID。

TarInfo.uname

用户名。

TarInfo.gname

组名。

TarInfo.pax_headers

包含相关pax扩展头的键值对的字典。

A TarInfo 对象还提供了一些方便的查询方法:

TarInfo.isfile()

返回 True 如果 Tarinfo 对象是常规文件。

TarInfo.isreg()

等同于 isfile() .

TarInfo.isdir()

返回 True 如果是目录。

TarInfo.issym()

返回 True 如果它是一个符号链接。

TarInfo.islnk()

返回 True 如果是硬链接。

TarInfo.ischr()

返回 True 如果是字符设备。

TarInfo.isblk()

返回 True 如果它是一个阻塞设备。

TarInfo.isfifo()

返回 True 如果是先进先出。

TarInfo.isdev()

返回 True 如果它是字符设备、块设备或FIFO之一。

命令行界面

3.4 新版功能.

这个 tarfile 模块提供了一个简单的命令行接口来与tar档案进行交互。

如果要创建新的tar存档,请在 -c 选项,然后列出应包含的文件名:

$ python -m tarfile -c monty.tar  spam.txt eggs.txt

传递目录也是可以接受的:

$ python -m tarfile -c monty.tar life-of-brian_1979/

如果要将tar存档提取到当前目录中,请使用 -e 选项:

$ python -m tarfile -e monty.tar

您还可以通过传递目录的名称将tar存档提取到其他目录中:

$ python -m tarfile -e monty.tar  other-dir/

有关tar存档中的文件列表,请使用 -l 选项:

$ python -m tarfile -l monty.tar

命令行选项

-l <tarfile>
--list <tarfile>

列出tarfile中的文件。

-c <tarfile> <source1> ... <sourceN>
--create <tarfile> <source1> ... <sourceN>

从源文件创建tarfile。

-e <tarfile> [<output_dir>]
--extract <tarfile> [<output_dir>]

如果 output_dir 未指定。

-t <tarfile>
--test <tarfile>

测试tarfile是否有效。

-v, --verbose

详细输出。

实例

如何将整个tar存档提取到当前工作目录:

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()

如何提取tar存档的子集 TarFile.extractall() 使用生成器函数而不是列表:

import os
import tarfile

def py_files(members):
    for tarinfo in members:
        if os.path.splitext(tarinfo.name)[1] == ".py":
            yield tarinfo

tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()

如何从文件名列表中创建未压缩的tar存档:

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
    tar.add(name)
tar.close()

使用 with 声明:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

如何读取gzip压缩tar存档并显示一些成员信息:

import tarfile
tar = tarfile.open("sample.tar.gz", "r:gz")
for tarinfo in tar:
    print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
    if tarinfo.isreg():
        print("a regular file.")
    elif tarinfo.isdir():
        print("a directory.")
    else:
        print("something else.")
tar.close()

如何创建存档并使用 滤波器 参数在 TarFile.add() ::

import tarfile
def reset(tarinfo):
    tarinfo.uid = tarinfo.gid = 0
    tarinfo.uname = tarinfo.gname = "root"
    return tarinfo
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add("foo", filter=reset)
tar.close()

支持的tar格式

可以使用创建三种tar格式 tarfile 模块:

  • posix.1-1988 USTAR格式 (USTAR_FORMAT )。它支持最多256个字符的文件名和最多100个字符的链接名。最大文件大小为8 Gib。这是一种旧的、有限的但得到广泛支持的格式。

  • GNU tar格式 (GNU_FORMAT )。它支持长文件名和链接名、大于8 GiB的文件和稀疏文件。它实际上是GNU/Linux系统上的标准。 tarfile 完全支持长名称的GNU tar扩展,稀疏文件支持是只读的。

  • posix.1-2001 pax格式 (PAX_FORMAT )它是最灵活的格式,几乎没有限制。它支持长文件名和链接名、大文件,并以可移植的方式存储路径名。现代tar实现,包括gnu tar、bsdtar/libarchive和star,完全支持扩展 pax 功能;一些旧的或未维护的库可能不会,但应该处理 pax 档案,就好像它们在普遍支持下一样 乌斯特 格式。它是新存档的当前默认格式。

    它扩展了现有的 乌斯特 为不能以其他方式存储的信息设置额外标题格式。pax头有两种风格:扩展头只影响后续的文件头,全局头对完整的存档有效,并影响以下所有文件。pax头中的所有数据都编码在 UTF-8 为了便于携带。

tar格式还有一些变体可以读取,但不能创建:

  • 古老的V7格式。这是UnixSeventhEdition的第一个tar格式,只存储常规文件和目录。名称不能超过100个字符,没有用户/组名称信息。有些归档文件在使用非ASCII字符的字段的情况下计算错误的头校验和。

  • sunos tar扩展格式。此格式是posix.1-2001 pax格式的变体,但不兼容。

Unicode问题

tar格式最初是为在磁带驱动器上进行备份而设计的,主要关注于保存文件系统信息。目前,tar档案通常用于网络上的文件分发和交换。原始格式(这是所有其他格式的基础)的一个问题是,没有支持不同字符编码的概念。例如,在 UTF-8 无法在上正确读取系统 Latin-1 如果包含非- ASCII 字符。文本元数据(如文件名、链接名、用户/组名)将出现损坏。不幸的是,无法自动检测存档的编码。pax格式是为解决这个问题而设计的。它使用通用字符编码存储非ASCII元数据 UTF-8 .

字符转换的详细信息 tarfileencodingerrors 的关键字参数 TarFile 类。

encoding 定义用于存档中元数据的字符编码。默认值为 sys.getfilesystemencoding()'ascii' 作为回退。根据归档文件是读取还是写入,元数据必须解码或编码。如果 encoding 未正确设置,此转换可能失败。

这个 errors 参数定义如何处理无法转换的字符。可能的值列在第节 错误处理程序 . 默认方案为 'surrogateescape' python还将其用于其文件系统调用,请参见 文件名、命令行参数和环境变量 .

为了 PAX_FORMAT 存档(默认值), encoding 通常不需要,因为所有元数据都是使用 UTF-8 . encoding 仅在二进制PAX头被解码或存储具有代理项字符的字符串时才使用。