On this page
12.5. tarfile —读写 tar 存档文件
2.3 版的新Function。
源代码: Lib/tarfile.py
tarfile模块可以读取和写入 tarFiles,包括使用 gzip 或 bz2 压缩的 Files。使用zipfile模块读取或写入.zip
文件,或使用shutil中的更高级Function。
一些事实和数据:
对 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 *)- 返回TarFile对象作为路径名* name *。有关TarFile对象和允许的关键字参数的详细信息,请参见TarFile Objects。
- mode *必须是格式为
'filemode[:compression]'
的字符串,默认为'r'
。这是模式组合的完整列表:
mode | action |
---|---|
'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。当前可能的模式:
Mode | Action |
---|---|
'r|*' |
打开 tar 数据块流以透明压缩方式进行读取。 |
'r|' |
打开未压缩的 tar 块的“流”以进行读取。 |
'r|gz' |
打开一个 gzip 压缩的* stream *进行阅读。 |
'r|bz2' |
打开一个 bzip2 压缩的* stream *进行读取。 |
'w|' |
打开未压缩的* stream *进行写入。 |
'w|gz' |
打开一个压缩的* stream * gzip 进行编写。 |
'w|bz2' |
打开一个 bzip2 压缩的* stream *进行写入。 |
类别
tarfile.
TarFile
- 读写 tarFiles 的类。不要直接使用此类,最好使用tarfile.open()。参见TarFile Objects。
tarfile.
is_tarfile
(* name *)-
- class *
tarfile.
TarFileCompat
(* filename , mode ='r', compression = TAR_PLAIN *)
- class *
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
时引发。
- 在使用TarFile.extract()时引发非致命错误,但仅在
以下常量在模块级别可用:
tarfile.
ENCODING
- 默认字符编码:Windows 上为
'utf-8'
,否则为sys.getfilesystemencoding()返回的值。
- 默认字符编码:Windows 上为
exception
tarfile.
HeaderError
- 如果它获得的缓冲区无效,则由TarInfo.frombuf()引发。
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。
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 *)
- 以下所有自变量都是可选的,也可以作为实例属性进行访问。
- class *
name 是归档文件的路径名。如果给出 fileobj *,可以Ellipsis。在这种情况下,将使用文件对象的
name
属性(如果存在)。mode *是
'r'
以便从现有 Files 中读取,'a'
可以将数据追加到现有文件中,或者'w'
可以创建一个新文件来覆盖现有文件。
如果给出* fileobj ,则用于读取或写入数据。如果可以确定,则 mode 被 fileobj *的 mode 覆盖。 * fileobj *将从位置 0 开始使用。
Note
TarFile关闭时,* fileobj *没有关闭。
- format *控制 Files 格式。它必须是在模块级别定义的常量USTAR_FORMAT,GNU_FORMAT或PAX_FORMAT之一。
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
,则所有致命*错误都会引发为OSError或IOErrorexception。如果为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 *)
Note
如果成员在存档中出现多次,则假定其最后一次出现是最新版本。
TarFile.
getmembers
( )- 以TarInfo对象列表的形式返回存档的成员。该列表与存档中的成员具有相同的 Sequences。
TarFile.
getnames
( )- 将成员作为其姓名列表返回。它与getmembers()返回的列表具有相同的 Sequences。
TarFile.
list
(* verbose = True *)TarFile.
next
( )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
(成员)
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()创建。
- 将TarInfo对象* tarinfo 添加到存档中。如果给定 fileobj *,则从中读取
Note
在 Windows 平台上,* fileobj *应该始终以'rb'
模式打开,以避免对文件大小产生刺激。
TarFile.
gettarinfo
(* name = None , arcname = None , fileobj = None *)
您可以先修改TarInfo的某些属性,然后再使用addfile()添加它。如果文件对象不是位于文件开头的普通文件对象,则可能需要修改诸如size的属性。诸如GzipFile之类的对象就是这种情况。 name也可以被修改,在这种情况下,* arcname *可以是虚拟字符串。
TarFile.
close
( )- 关闭TarFile。在写入模式下,两个结尾为零的块将添加到归档中。
TarFile.
posix
- 将此设置为True等效于将format属性设置为USTAR_FORMAT,False等效于GNU_FORMAT。
在版本 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对象。
- class *
TarInfo.
frombuf
(* buf *)- 从字符串缓冲区* buf *创建并返回TarInfo对象。
2.6 版中的新增Function:如果缓冲区无效,则引发HeaderError。
2.6 版的新Function。
TarInfo.
tobuf
(* format = DEFAULT_FORMAT , encoding = ENCODING , errors ='strict'*)
在 2.6 版中进行了更改:添加了自变量。
TarInfo
对象具有以下公共数据属性:
TarInfo.
name
- 存档成员的名称。
TarInfo.
size
- 大小(以字节为单位)。
TarInfo.
mtime
- 上次修改时间。
TarInfo.
mode
- Permission bits.
TarInfo.
type
- 文件类型。 * type *通常是以下常量之一:
REGTYPE
,AREGTYPE
,LNKTYPE
,SYMTYPE
,DIRTYPE
,FIFOTYPE
,CONTTYPE
,CHRTYPE
,BLKTYPE
,GNUTYPE_SPARSE
。若要更方便地确定TarInfo对象的类型,请使用下面的is*()
方法。
- 文件类型。 * type *通常是以下常量之一:
TarInfo.
linkname
- 目标文件名的名称,仅存在于
LNKTYPE
和SYMTYPE
类型的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
( )- 与isfile()相同。
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'
,以确保名称信息不会被忽视。