13.6. tarfile
— 读取与压缩tar文件¶
源代码: Lib / tarfile.py
tarfile
模块用于读取或者压缩tar文件,可针对gzip、bz2或lzma等格式文件进行相关操作。假如希望对.zip
格式文件进行操作,则应使用zipfile
模块,或者使用shutil里的高级函数。
一些事实和数字:
- 如果相应的模块可用,则读取并写入
gzip
,bz2
和lzma
压缩归档。 - 读/写支持POSIX.1-1988(ustar)格式。
- 对包括longname和longlink扩展的GNU tar格式的读/写支持,对稀疏扩展的所有变体的只读支持,包括恢复稀疏文件。
- 对POSIX.1-2001(pax)格式的读/写支持。
- 处理目录,常规文件,硬链接,符号链接,fifos,字符设备和块设备,并能够获取和恢复文件信息,如时间戳,访问权限和所有者。
在版本3.3中更改:添加对lzma
压缩的支持。
-
tarfile.
open
(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)¶ 为路径名名称返回
TarFile
对象。有关TarFile
对象和允许的关键字参数的详细信息,请参阅TarFile Objects。mode必须是
'filemode[:compression]'
形式的字符串,默认为'r'
。这里是模式组合的完整列表:模式 行动 'r' 或 'r:*'
通过透明压缩打开阅读(推荐)。 'r:'
无压缩打开专用读取。 'r:gz'
使用gzip压缩打开阅读。 'r:bz2'
使用bzip2压缩打开阅读。 'r:xz'
使用lzma压缩打开阅读。 'x'
或'x:'
完全无压缩地创建tarfile。引发 FileExistsError
异常(如果它已存在)。'x:gz'
使用gzip压缩创建tarfile。引发 FileExistsError
异常(如果它已存在)。'x:bz2'
使用bzip2压缩创建tarfile。引发 FileExistsError
异常(如果它已存在)。'x:xz'
使用lzma压缩创建tarfile。引发 FileExistsError
异常(如果它已存在)。'a' 或 'a:'
打开,无需压缩。如果文件不存在,则创建该文件。 'w' 或 'w:'
打开未压缩的写入。 'w:gz'
打开gzip压缩写入。 'w:bz2'
打开bzip2压缩写。 'w:xz'
打开lzma压缩写。 请注意,不能使用
'a:gz'
,'a:bz2'
或'a:xz'
如果模式不适合打开某个(压缩)文件进行读取,则会出现ReadError
。使用模式'r'
可避免此情况。如果不支持压缩方法,则会引发CompressionError
。如果指定fileobj,它将用作名称以二进制模式打开的file object的替代。它应该在位置0。
For modes
'w:gz'
,'r:gz'
,'w:bz2'
,'r:bz2'
,'x:gz'
,'x:bz2'
,tarfile.open()
accepts the keyword argument compresslevel (default9
) to specify the compression level of the file.对于特殊用途,还有模式的第二种格式:
'filemode|[compression]'
。tarfile.open()
将返回一个TarFile
对象,该对象将其数据作为块流处理。不会对文件进行随机搜索。如果给定,fileobj可以是具有read()
或write()
方法的任何对象(取决于t5>)。bufsize指定块大小并默认为20 * 512
字节。使用此变体与例如sys.stdin
,套接字file object或磁带设备。然而,这样的TarFile
对象受限,因为它不允许随机访问,参见Examples。当前可能的模式:模式 行动 'r|*'
打开用于透明压缩读取的tar块的流。 'r|'
打开未压缩的tar块的流以进行读取。 'r|gz'
打开gzip压缩的流进行阅读。 'r|bz2'
打开bzip2压缩的流进行阅读。 'r|xz'
打开lzma压缩的流进行阅读。 'w|'
打开未压缩的流进行写入。 'w|gz'
打开gzip压缩的流进行写入。 'w|bz2'
打开用于写入的bzip2压缩流。 'w|xz'
打开lzma压缩的流进行写入。 在版本3.5中已更改:添加了
'x'
(独占创建)模式。
- class
tarfile.
TarFile
¶ 读写tar存档的类。不要直接使用这个类:use
tarfile.open()
。请参阅TarFile Objects。
tarfile
模块定义了以下例外:
- exception
tarfile.
CompressionError
¶ 当不支持压缩方法或无法正确解码数据时引发。
- exception
tarfile.
ExtractError
¶ 使用
TarFile.extract()
时,但仅在TarFile.errorlevel
==时产生非致命错误 2
。
- exception
tarfile.
HeaderError
¶ 由
TarInfo.frombuf()
引发,如果它获得的缓冲区无效。
以下常量在模块级可用:
-
tarfile.
ENCODING
¶ Windows上的默认字符编码:
'utf-8'
否则为sys.getfilesystemencoding()
返回的值。
以下每个常数定义tarfile
模块能够创建的tar归档格式。有关详细信息,请参阅Supported tar formats一节。
-
tarfile.
USTAR_FORMAT
¶ POSIX.1-1988(ustar)格式。
-
tarfile.
GNU_FORMAT
¶ GNU tar格式。
-
tarfile.
PAX_FORMAT
¶ POSIX.1-2001(pax)格式。
-
tarfile.
DEFAULT_FORMAT
¶ 用于创建归档的默认格式。目前为
GNU_FORMAT
。
也可以看看
- 模块
zipfile
zipfile
标准模块的文档。- Archiving operations
- 由标准
shutil
模块提供的高级存档工具的文档。 - GNU tar手动,基本tar格式
- tar归档文件的文档,包括GNU tar扩展。
13.6.1. TarFile Objects¶
TarFile
对象提供了一个tar归档文件的接口。tar归档是一系列块。存档成员(存储文件)由标题块后跟数据块组成。可以将文件存储在tar存档中多次。每个归档成员由TarInfo
对象表示,有关详细信息,请参阅TarInfo Objects。
TarFile
对象可以在with
语句中用作上下文管理器。当块完成时,它将自动关闭。请注意,如果出现例外情况,打开的写作存档将不会最终确定;只有内部使用的文件对象将被关闭。有关用例,请参见Examples部分。
版本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是归档的路径名。如果给出fileobj,则可以省略。在这种情况下,如果文件对象的
name
属性存在,则使用该属性。模式是从现有档案读取
'r'
,'a'
以将数据附加到现有文件,'w'
创建新文件覆盖现有文件,或'x'
创建新文件(如果它不存在)。如果给定fileobj,则用于读取或写入数据。如果可以确定,fileobj的模式将覆盖模式。fileobj将从位置0开始使用。
注意
当
TarFile
关闭时,fileobj未关闭。格式控制归档格式。它必须是在模块级定义的常量
USTAR_FORMAT
,GNU_FORMAT
或PAX_FORMAT
之一。可以使用tarinfo参数替换默认的
TarInfo
类。如果解引用为
False
,请向归档添加符号链接和硬链接。如果True
,请将目标文件的内容添加到归档中。这对不支持符号链接的系统没有影响。如果ignore_zeros为
False
,则将空块视为归档的结尾。如果它True
,则跳过空(和无效)块,并尝试获取尽可能多的成员。这仅对读取级联或损坏的存档有用。调试可以从
0
(无调试消息)到3
(所有调试消息)设置。消息写入sys.stderr
。如果errorlevel为
0
,则使用TarFile.extract()
时,将忽略所有错误。但是,当调试启用时,它们在调试输出中显示为错误消息。如果1
,则所有致命错误都会作为OSError
异常引发。如果2
,所有非致命错误也会作为TarError
异常引发。编码和错误参数定义要用于读取或写入归档的字符编码,以及如何处理转换错误。默认设置适用于大多数用户。有关详细信息,请参阅Unicode issues一节。
pax_headers参数是字符串的可选字典,如果格式是
PAX_FORMAT
,则字符串将添加为pax全局标题。在版本3.2中已更改:使用
'surrogateescape'
作为错误参数的默认值。在版本3.5中已更改:添加了
'x'
(独占创建)模式。
- classmethod
TarFile.
open
(...)¶ 替代构造函数。The
tarfile.open()
function is actually a shortcut to this classmethod.
-
TarFile.
getnames
()¶ 返回成员作为他们的名字的列表。它与由
getmembers()
返回的列表具有相同的顺序。
-
TarFile.
list
(verbose=True, *, members=None)¶ 将目录打印到
sys.stdout
。如果verbose是False
,则只打印成员的名称。如果True
,则产生类似于ls -l 的输出。如果给出可选的成员,它必须是由getmembers()
返回的列表的子集。在版本3.5中已更改:添加了成员参数。
-
TarFile.
extractall
(path=".", members=None, *, numeric_owner=False)¶ 将归档中的所有成员解压缩到当前工作目录或目录路径。如果给出了可选的成员,它必须是由
getmembers()
返回的列表的子集。在提取所有成员后,设置所有者,修改时间和权限等目录信息。这是为了解决两个问题:目录的修改时间每次在其中创建文件时重置。并且,如果目录的权限不允许写入,则解压缩文件将失败。如果numeric_owner为
True
,tarfile中的uid和gid数字用于设置提取的文件的所有者/组。否则,使用来自tarfile的命名值。警告
切勿在未经预先检查的情况下从不可信来源中提取存档。可能在路径之外创建文件,例如具有以
"/"
开头的绝对文件名的成员或具有两个点".."
的文件名。在版本3.5中已更改:添加了numeric_only参数。
-
TarFile.
extract
(member, path="", set_attrs=True, *, numeric_owner=False)¶ 使用其全名将成员从归档提取到当前工作目录。其文件信息尽可能精确地提取。成员可以是文件名或
TarInfo
对象。您可以使用路径指定其他目录。除非set_attrs为false,否则设置文件属性(owner,mtime,mode)。如果numeric_owner为
True
,tarfile中的uid和gid数字用于设置提取的文件的所有者/组。否则,使用来自tarfile的命名值。注意
extract()
方法不处理几个提取问题。在大多数情况下,您应该考虑使用extractall()
方法。警告
请参阅
extractall()
的警告。在版本3.2中已更改:添加了set_attrs参数。
在版本3.5中已更改:添加了numeric_only参数。
-
TarFile.
extractfile
(member)¶ 从存档中提取成员作为文件对象。成员可以是文件名或
TarInfo
对象。如果成员是常规文件或链接,则会返回io.BufferedReader
对象。否则,返回None
。在版本3.3中更改:返回
io.BufferedReader
对象。
-
TarFile.
add
(name, arcname=None, recursive=True, exclude=None, *, filter=None)¶ 将文件名称添加到归档中。名称可以是任何类型的文件(目录,fifo,符号链接等)。如果给定,arcname指定归档中文件的备用名称。默认情况下,目录以递归方式添加。这可以通过将递归设置为
False
来避免。如果给出exclude,它必须是一个函数,它需要一个文件名参数并返回一个布尔值。根据此值,相应的文件被排除(True
)或添加(False
)。如果指定filter,它必须是一个关键字参数。它应该是一个接受TarInfo
对象参数并返回更改的TarInfo
对象的函数。如果它返回None
,则将从档案中排除TarInfo
对象。有关示例,请参见Examples。在版本3.2中更改:添加了过滤器参数。
自版本3.2后已弃用: 排除参数已弃用,请改用filter参数。
-
TarFile.
addfile
(tarinfo, fileobj=None)¶ 将
TarInfo
对象tarinfo添加到归档中。如果给定fileobj,它应该是一个binary file,并且从它读取tarinfo.size
字节并将其添加到归档中。您可以直接创建TarInfo
对象,也可以使用gettarinfo()
。
-
TarFile.
gettarinfo
(name=None, arcname=None, fileobj=None)¶ 从现有文件的
os.stat()
或等效结果创建TarInfo
对象。该文件由名称命名,或者用文件描述器指定为file object fileobj。If given, arcname specifies an alternative name for the file in the archive, otherwise, the name is taken from fileobj’sname
attribute, or the name argument. 名称应为文本字符串。您可以修改某些
TarInfo
的属性,然后使用addfile()
添加它。如果文件对象不是位于文件开头的普通文件对象,则可能需要修改size
等属性。对于诸如GzipFile
的对象就是这种情况。还可以修改name
,在这种情况下,arcname可以是虚拟字符串。
-
TarFile.
pax_headers
¶ 包含pax全局头的键/值对的字典。
13.6.2. TarInfo Objects¶
TarInfo
对象表示TarFile
中的一个成员。除了存储文件的所有必需属性(如文件类型,大小,时间,权限,所有者等)),它提供了一些有用的方法来确定它的类型。它不包含文件的数据本身。
TarInfo
对象由TarFile
的方法getmember()
,getmembers()
和gettarinfo()
。
- classmethod
TarInfo.
frombuf
(buf, encoding, errors)¶ 从字符串缓冲区buf创建并返回
TarInfo
对象。如果缓冲区无效,则引发
HeaderError
。
-
TarInfo.
tobuf
(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')¶ 从
TarInfo
对象创建字符串缓冲区。有关参数的信息,请参阅TarFile
类的构造函数。在版本3.2中更改:使用
'surrogateescape'
作为错误参数的默认值。
TarInfo
对象具有以下公共数据属性:
-
TarInfo.
name
¶ 存档成员的名称。
-
TarInfo.
size
¶ 大小(字节)。
-
TarInfo.
mtime
¶ 上次修改时间。
-
TarInfo.
mode
¶ 权限位。
-
TarInfo.
type
¶ 文件类型。类型通常是以下常量之一:
REGTYPE
,AREGTYPE
,LNKTYPE
,SYMTYPE
,DIRTYPE
,FIFOTYPE
,CONTTYPE
,CHRTYPE
,BLKTYPE
,GNUTYPE_SPARSE
。要更方便地确定TarInfo
对象的类型,请使用下面的is*()
方法。
-
TarInfo.
uid
¶ 最初存储此成员的用户的用户标识。
-
TarInfo.
gid
¶ 最初存储此成员的用户的组ID。
-
TarInfo.
uname
¶ 用户名。
-
TarInfo.
gname
¶ 组名称。
-
TarInfo.
pax_headers
¶ 包含关联的pax扩展头的键/值对的字典。
TarInfo
对象还提供了一些方便的查询方法:
13.6.3. Command Line Interface¶
版本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
13.6.4. 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", 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()
13.6.5. Supported tar formats¶
有三种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实现今天能够正确处理pax档案。pax格式是对现有ustar格式的扩展。它使用额外的头信息,否则不能存储。有两种类型的pax头:扩展头仅影响后续文件头,全局头对整个归档有效,并影响所有以下文件。出于可移植性的原因,pax头中的所有数据都编码在UTF-8中。
还有一些tar格式的变体,可以读取但不创建:
- 古代的V7格式。这是Unix第七版的第一个tar格式,只存储常规文件和目录。名称不能超过100个字符,没有用户/组名称信息。某些归档在具有非ASCII字符的字段的情况下具有错误计算的头校验和。
- SunOS tar扩展格式。此格式是POSIX.1-2001 pax格式的变体,但不兼容。
13.6.6. Unicode issues¶
tar格式最初是为了在磁带驱动器上进行备份,主要侧重于保留文件系统信息。现在tar存档通常用于文件分发和通过网络交换档案。原始格式(这是所有其他格式的基础)的一个问题是没有支持不同字符编码的概念。例如,如果Latin-1系统中包含非ASCII,则在UTF-8系统上创建的普通tar存档无法正确读取>字符。文本元数据(如文件名,链接名,用户/组名称)将显示已损坏。不幸的是,没有办法自动检测归档的编码。pax格式被设计来解决这个问题。它使用通用字符编码UTF-8存储非ASCII元数据。
tarfile
中的字符转换详细信息由TarFile
类的编码和错误关键字参数控制。
encoding定义要用于存档中元数据的字符编码。默认值为sys.getfilesystemencoding()
或'ascii'
作为后备。根据归档是读还是写,元数据必须解码或编码。如果未正确设置编码,则此转换可能会失败。
errors参数定义如何处理无法转换的字符。可能的值在Error Handlers部分中列出。默认方案是Python还用于其文件系统调用的'surrogateescape'
,请参阅File Names, Command Line Arguments, and Environment Variables。
在PAX_FORMAT
档案的情况下,通常不需要编码,因为所有元数据都使用UTF-8存储。encoding is only used in the rare cases when binary pax headers are decoded or when strings with surrogate characters are stored.