12.5. tarfile —读写 tar 存档文件

2.3 版的新Function。

源代码: Lib/tarfile.py


tarfile模块可以读取和写入 tarFiles,包括使用 gzip 或 bz2 压缩的 Files。使用zipfile模块读取或写入.zip文件,或使用shutil中的更高级Function。

一些事实和数据:

  • 如果各个模块可用,则读取和写入gzipbz2压缩 Files。

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

  • 对 GNU tar 格式(包括* longname longlink 扩展)的读/写支持,对 sparse *扩展的只读支持。

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

2.6 版的新Function。

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

Note

不支持多流 bzip2 文件的处理。诸如bz2file之类的模块可帮助您克服这一问题。

  • tarfile. open(* name = None mode ='r' fileobj = None bufsize = 10240 ** kwargs *)
  • mode *必须是格式为'filemode[:compression]'的字符串,默认为'r'。这是模式组合的完整列表:
modeaction
'r' or 'r:*'打开以透明压缩方式阅读(推荐)。
'r:'仅打开即可阅读,无需压缩。
'r:gz'pass gzip 压缩打开以供阅读。
'r:bz2'打开以使用 bzip2 压缩进行阅读。
'a' or 'a:'打开以进行追加而没有压缩。如果文件不存在,则创建该文件。
'w' or 'w:'打开以进行未压缩的写入。
'w:gz'打开以进行 gzip 压缩书写。
'w:bz2'打开以进行 bzip2 压缩写入。

请注意,不能使用'a:gz''a:bz2'。如果* mode 不适合打开某个(压缩的)文件进行读取,则会引发ReadError。使用 mode * 'r'避免这种情况。如果不支持压缩方法,则会引发CompressionError

如果指定了* fileobj ,它将用作为 name *打开的文件对象的替代。它应该位于位置 0.

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

出于特殊目的,* mode 还有第二种格式:'filemode|[compression]'tarfile.open()将返回一个TarFile对象,该对象将其数据作为块流处理。不会对文件进行随机查找。如果给定, fileobj 可以是具有read()write()方法的任何对象(取决于 mode *)。 * bufsize *指定块大小,默认为20 * 512字节。结合使用此变体,例如sys.stdin,套接字文件对象或磁带设备。但是,这样的TarFile对象受到限制,因为它不允许随机访问,请参见Examples。当前可能的模式:

ModeAction
'r|*'打开 tar 数据块流以透明压缩方式进行读取。
'r|'打开未压缩的 tar 块的“流”以进行读取。
'r|gz'打开一个 gzip 压缩的* stream *进行阅读。
'r|bz2'打开一个 bzip2 压缩的* stream *进行读取。
'w|'打开未压缩的* stream *进行写入。
'w|gz'打开一个压缩的* stream * gzip 进行编写。
'w|bz2'打开一个 bzip2 压缩的* stream *进行写入。
  • 类别 tarfile. TarFile

  • tarfile. is_tarfile(* name *)

    • 如果* name *是 tar 存档文件,则返回Truetarfile模块可以读取该文件。
    • class * tarfile. TarFileCompat(* filename mode ='r' compression = TAR_PLAIN *)
    • 类,用于pass类似zipfile的界面来限制对 tar 归档文件的访问。有关更多详细信息,请查阅zipfile模块的文档。 * compression *必须是以下常量之一:
  • TAR_PLAIN

    • 未压缩的 tar 存档的常量。
  • TAR_GZIPPED

    • gzip压缩 tar 存档的常量。

自 2.6 版起弃用:TarFileCompat类已在 Python 3 中删除。

  • exception tarfile. TarError

    • 所有tarfile个 exception 的 Base Class。
  • exception tarfile. ReadError

    • 在打开 tar 归档文件时引发,该归档文件不能由tarfile模块处理,或者由于某种原因无效。
  • exception tarfile. CompressionError

    • 当不支持压缩方法或无法正确解码数据时引发。
  • exception tarfile. StreamError

    • 针对类似流的TarFile对象的典型限制而提出。
  • exception tarfile. ExtractError

    • 在使用TarFile.extract()时引发非致命错误,但仅在TarFile.errorlevel == 2时引发。

以下常量在模块级别可用:

2.6 版的新Function。

以下每个常量定义tarfile模块能够创建的 tar 存档格式。有关详情,请参见支持的 tar 格式部分。

  • tarfile. USTAR_FORMAT

    • POSIX.1-1988(ustar)格式。
  • tarfile. GNU_FORMAT

    • GNU tar 格式。
  • tarfile. PAX_FORMAT

    • POSIX.1-2001(pax)格式。
  • tarfile. DEFAULT_FORMAT

    • 用于创建 Files 的默认格式。当前是GNU_FORMAT

See also

12.5.1. TarFile 对象

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

TarFile对象可用作with语句中的上下文 Management 器。块完成后,它将自动关闭。请注意,如果发生 exceptions,打开的存档归档文件将不会finally确定;仅内部使用的文件对象将被关闭。有关用例,请参见Examples部分。

2.7 版的新Function:添加了对上下文 Management 协议的支持。

    • class * tarfile. TarFile((name = None mode ='r' fileobj = None format = DEFAULT_FORMAT tarinfo = TarInfo dereference = False ignore_zeros = False *, * encoding = ENCODING errors = None pax_headers = None debug = 0 errorlevel = 0 *)
    • 以下所有自变量都是可选的,也可以作为实例属性进行访问。
  • name 是归档文件的路径名。如果给出 fileobj *,可以Ellipsis。在这种情况下,将使用文件对象的name属性(如果存在)。

  • mode *是'r'以便从现有 Files 中读取,'a'可以将数据追加到现有文件中,或者'w'可以创建一个新文件来覆盖现有文件。

如果给出* fileobj ,则用于读取或写入数据。如果可以确定,则 mode fileobj *的 mode 覆盖。 * fileobj *将从位置 0 开始使用。

Note

TarFile关闭时,* fileobj *没有关闭。

2.6 版的新Function。

  • tarinfo *参数可用于将默认的TarInfo类替换为另一类。

2.6 版的新Function。

如果* dereference *为False,则将符号链接和硬链接添加到存档。如果为True,则将目标文件的内容添加到存档中。这对不支持符号链接的系统没有影响。

如果* ignore_zeros *为False,则将一个空块视为存档的结尾。如果是True,请跳过空的(和无效的)块,并try获取尽可能多的成员。这仅对读取串联或损坏的 Files 有用。

  • debug *可以设置为0(无调试消息)到3(所有调试消息)。消息被写入sys.stderr

如果* errorlevel 0,则使用TarFile.extract()时将忽略所有错误。但是,启用调试后,它们将作为错误消息出现在调试输出中。如果为1,则所有致命*错误都会引发为OSErrorIOErrorexception。如果为2,则所有非致命错误也会作为TarError异常引发。

  • encoding errors *参数控制将字符串转换为 unicode 对象的方式,反之亦然。默认设置适用于大多数用户。有关详细信息,请参见第Unicode issues节。

2.6 版的新Function。

  • pax_headers 参数是 unicode 字符串的可选字典,如果 format *为PAX_FORMAT,则它将作为 pax 全局标题添加。

2.6 版的新Function。

  • 类方法 TarFile. open(* ... *)

    • 替代构造函数。 tarfile.open()函数实际上是该类方法的快捷方式。
  • TarFile. getmember(* name *)

    • 返回成员* name TarInfo对象。如果在存档中找不到 name *,则引发KeyError

Note

如果成员在存档中出现多次,则假定其最后一次出现是最新版本。

  • TarFile. getmembers ( )

    • TarInfo对象列表的形式返回存档的成员。该列表与存档中的成员具有相同的 Sequences。
  • TarFile. getnames ( )

    • 将成员作为其姓名列表返回。它与getmembers()返回的列表具有相同的 Sequences。
  • TarFile. list(* verbose = True *)

    • 将目录打印到sys.stdout。如果* verbose *为False,则仅打印成员的名称。如果是True,则产生类似于 ls -l 的输出。
  • TarFile. next ( )

    • 打开TarFile进行读取时,将存档的下一个成员作为TarInfo对象返回。如果没有更多可用,则返回None
  • TarFile. extractall(* path =“.” members = None *)

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

Warning

未经事先检查,切勿从不受信任的来源中提取 Files。文件可能是在* path *之外创建的,例如具有以"/"开头的绝对文件名或带有两个点".."的文件名的成员。

2.5 版的新Function。

  • TarFile. extract(* member path =“” *)
    • 使用成员的全名将成员从存档中提取到当前工作目录。尽可能准确地提取其文件信息。 * member 可以是文件名或TarInfo对象。您可以使用 path *指定其他目录。

Note

extract()方法无法解决多个提取问题。在大多数情况下,您应该考虑使用extractall()方法。

Warning

请参阅extractall()的警告。

  • TarFile. extractfile(成员)
    • 从存档中提取一个成员作为文件对象。 * member 可以是文件名或TarInfo对象。如果 member 是常规文件,则返回类似文件的对象。如果 member 是链接,则从链接的目标构造类似文件的对象。如果 member *都不是上述任何一个,则返回None

Note

类文件对象是只读的。它提供了read()readline()readlines()seek()tell()close()的方法,并且还支持其上的迭代。

  • TarFile. add(* name arcname = None recursive = True exclude = None filter = None *)
    • 将文件* name *添加到存档中。 * name 可以是任何类型的文件(目录,fifo,符号链接等)。如果给定,则 arcname 指定存档中文件的备用名称。默认情况下,将以递归方式添加目录。可以pass将 recursive 设置为False来避免这种情况。如果给定 exclude ,则它必须是一个使用一个文件名参数并返回布尔值的函数。根据此值,相应文件被排除(True)或添加(False)。如果指定了 filter *,则它必须是一个接受TarInfo对象参数并返回更改后的TarInfo对象的函数。如果改为返回None,则将TarInfo对象从存档中排除。有关示例,请参见Examples

在 2.6 版中进行了更改:添加了* exclude *参数。

在 2.7 版中进行了更改:添加了* filter *参数。

从 2.7 版开始不推荐使用:* exclude 参数不推荐使用,请改用 filter 参数。为了获得最大的可移植性,应将 filter 用作关键字参数而不是位置参数,以便在finally删除 exclude *时不会影响代码。

  • TarFile. addfile(* tarinfo fileobj = None *)
    • TarInfo对象* tarinfo 添加到存档中。如果给定 fileobj *,则从中读取tarinfo.size个字节并将其添加到存档中。您可以直接创建TarInfo个对象,也可以使用gettarinfo()创建。

Note

在 Windows 平台上,* fileobj *应该始终以'rb'模式打开,以避免对文件大小产生刺激。

  • TarFile. gettarinfo(* name = None arcname = None fileobj = None *)
    • 根据现有文件的os.stat()的结果或等效结果创建一个TarInfo对象。该文件以* name 命名,或指定为带有文件 Descriptors 的文件对象 fileobj 。如果已给定,则 arcname 指定存档中文件的替代名称,否则,该名称取自 fileobj name属性或 name *参数。

您可以先修改TarInfo的某些属性,然后再使用addfile()添加它。如果文件对象不是位于文件开头的普通文件对象,则可能需要修改诸如size的属性。诸如GzipFile之类的对象就是这种情况。 name也可以被修改,在这种情况下,* arcname *可以是虚拟字符串。

在版本 2.4 中更改:* posix *默认为False

从 2.6 版开始不推荐使用:而是使用format属性。

  • TarFile. pax_headers
    • 包含 pax 全局 Headers 的键/值对的字典。

2.6 版的新Function。

12.5.2. TarInfo 对象

TarInfo对象代表TarFile中的一个成员。除了存储文件的所有必需属性(如文件类型,大小,时间,权限,所有者等)之外,它还提供了一些有用的方法来确定其类型。它不包含文件本身的数据。

TarInfo对象是由TarFile的方法getmember()getmembers()gettarinfo()返回的。

    • class * tarfile. TarInfo(* name =“” *)
  • TarInfo. frombuf(* buf *)

    • 从字符串缓冲区* buf *创建并返回TarInfo对象。

2.6 版中的新增Function:如果缓冲区无效,则引发HeaderError

  • TarInfo. fromtarfile(* tarfile *)
    • TarFile对象* tarfile *中读取下一个成员,并将其作为TarInfo对象返回。

2.6 版的新Function。

  • TarInfo. tobuf(* format = DEFAULT_FORMAT encoding = ENCODING errors ='strict'*)
    • TarInfo对象创建一个字符串缓冲区。有关参数的信息,请参见TarFile类的构造函数。

在 2.6 版中进行了更改:添加了自变量。

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

  • TarInfo. name

    • 存档成员的名称。
  • TarInfo. size

    • 大小(以字节为单位)。
  • TarInfo. mtime

    • 上次修改时间。
  • TarInfo. mode

    • Permission bits.
  • TarInfo. type

    • 文件类型。 * type *通常是以下常量之一:REGTYPEAREGTYPELNKTYPESYMTYPEDIRTYPEFIFOTYPECONTTYPECHRTYPEBLKTYPEGNUTYPE_SPARSE。若要更方便地确定TarInfo对象的类型,请使用下面的is*()方法。
  • TarInfo. linkname

    • 目标文件名的名称,仅存在于LNKTYPESYMTYPE类型的TarInfo个对象中。
  • TarInfo. uid

    • 最初存储此成员的用户的用户 ID。
  • TarInfo. gid

    • 最初存储此成员的用户的组 ID。
  • TarInfo. uname

    • User name.
  • TarInfo. gname

    • Group name.
  • TarInfo. pax_headers

    • 包含关联的 pax 扩展 Headers 的键/值对的字典。

2.6 版的新Function。

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

  • TarInfo. isfile ( )

    • 如果Tarinfo对象是常规文件,则返回True
  • TarInfo. isreg ( )

  • TarInfo. isdir ( )

    • 如果它是目录,则返回True
  • TarInfo. issym ( )

    • 如果它是符号链接,则返回True
  • TarInfo. islnk ( )

    • 如果是硬链接,则返回True
  • TarInfo. ischr ( )

    • 如果它是字符设备,则返回True
  • TarInfo. isblk ( )

    • 如果它是块设备,则返回True
  • TarInfo. isfifo ( )

    • 如果是 FIFO,则返回True
  • TarInfo. isdev ( )

    • 如果它是字符设备,块设备或 FIFO 之一,则返回True

12.5.3. Examples

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

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

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

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",
    if tarinfo.isreg():
        print "a regular file."
    elif tarinfo.isdir():
        print "a directory."
    else:
        print "something else."
tar.close()

如何使用TarFile.add()中的* filter *参数创建 Files 并重置用户信息:

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

12.5.4. 支持的 tar 格式

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

  • POSIX.1-1988 ustar 格式(USTAR_FORMAT)。它支持的文件名最大长度为 256 个字符,而链接名的最大长度为 100 个字符。Files 大小上限为 8 GB。这是一种古老且有限但受广泛支持的格式。

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

  • POSIX.1-2001 pax 格式(PAX_FORMAT)。这是最灵活的格式,几乎没有限制。它支持长文件名和链接名,大文件,并以可移植的方式存储路径名。但是,并非今天的所有 tar 实施都能够正确处理 pax 存档。

  • pax 格式是现有 ustar 格式的扩展。它使用额外的 Headers 来存储否则无法存储的信息。 paxHeaders 有两种类型:扩展 Headers 仅影响后续文件 Headers,全局 Headers 对完整存档有效,并影响所有后续文件。出于可移植性原因,paxHeaders 中的所有数据都以 UTF-8 *编码。

可以读取但无法创建的 tar 格式还有更多变体:

  • 古老的 V7 格式。这是 Unix Seventh Edition 中的第一种 tar 格式,仅存储常规文件和目录。名称不得超过 100 个字符,没有用户/组名称信息。对于具有非 ASCII 字符的字段,某些 Files 文件的 Headers 校验和计算错误。

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

12.5.5. Unicode 问题

tar 格式最初是为了在磁带驱动器上进行备份而设计的,其主要重点是保留文件系统信息。如今,tarFiles 通常用于文件分发和pass网络交换 Files。原始格式(所有其他格式仅仅是其变体)的一个问题是,没有支持不同字符编码的概念。例如,如果在* UTF-8 系统上创建的普通 tar 存档包含非 ASCII 字符,则无法在 Latin-1 *系统上正确读取。包含这些字符的名称(即文件名,链接名,用户/组名)将显示为已损坏。不幸的是,没有办法自动检测 Files 的编码。

pax 格式旨在解决此问题。它使用通用字符编码* UTF-8 存储非 ASCII 名称。读取 pax 存档时,这些 UTF-8 *名称将转换为本地文件系统的编码。

Unicode 转换的详细信息由TarFile类的* encoding errors *关键字参数控制。

  • encoding 的默认值为本地字符编码。它是根据sys.getfilesystemencoding()sys.getdefaultencoding()推导出的。在读取模式下, encoding 专门用于将 pax 存档中的 unicode 名称转换为本地字符编码的字符串。在写入模式下, encoding 的使用取决于所选的存档格式。在PAX_FORMAT的情况下,包含非 ASCII 字符的 Importing 名称需要先解码,然后再存储为 UTF-8 字符串。除非将 unicode 对象用作 Importing 名称,否则其他格式不使用 encoding *。将它们转换为 8 位字符串,然后再将其添加到存档中。

  • errors 参数定义如何对待无法与 encoding 进行转换的字符。 编解码器 Base Class部分中列出了可能的值。在读取模式下,还有一个附加方案'utf-8',这意味着不良字符被其 UTF-8 表示形式替代。这是默认方案。在写入模式下, errors *的默认值为'strict',以确保名称信息不会被忽视。