源代码:
Lib/tarfile.py
tarfile
模块可以用来读写 tar 归档,包括使用 gzip, bz2 和 lzma 压缩的归档。 请使用
zipfile
模块来读写
.zip
文件,或者使用
shutil
的高层级函数。
一些事实和数字:
读写
gzip
,
bz2
和
lzma
解压的归档要求相应的模块可用。
支持读取 / 写入 POSIX.1-1988 (ustar) 格式。
对 GNU tar 格式的读/写支持,包括
longname
和
longlink
扩展,对所有种类
sparse
扩展的只读支持,包括 sparse 文件的恢复。
对 POSIX.1-2001 (pax) 格式的读/写支持。
处理目录、正常文件、硬链接、符号链接、fifo 管道、字符设备和块设备,并且能够获取和恢复文件信息例如时间戳、访问权限和所有者等。
在 3.3 版本发生变更:
添加了对
lzma
压缩的支持。
在 3.12 版本发生变更:
归档文件使用
过滤器
来提取,这将可以限制令人惊讶/危险的特性,或确认它们符合预期并且归档文档受到完全信任。 在默认情况下,归档文档将受到完全信任,但此默认选项已被弃用并计划在 Python 3.14 中改变。
tarfile.
open
(
name
=
None
,
mode
=
'r'
,
fileobj
=
None
,
bufsize
=
10240
,
**
kwargs
)
针对路径名
name
返回
TarFile
对象。 有关
TarFile
对象以及所允许的关键字参数的详细信息请参阅
TarFile 对象
。
mode
必须是
'filemode[:compression]'
形式的字符串,其默认值为
'r'
。 以下是模式组合的完整列表:
action
'r'
or
'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'
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
。
如果指定了
fileobj
,它会被用作对应于
name
的以二进制模式打开的
file object
的替代。 它会被设定为处在位置 0。
对于
'w:gz'
,
'x:gz'
,
'w|gz'
,
'w:bz2'
,
'x:bz2'
,
'w|bz2'
等模式,
tarfile.open()
接受关键字参数
compresslevel
(默认值为
9
) 用于指定文件的压缩等级。
对于
'w:xz'
和
'x:xz'
模式,
tarfile.open()
接受关键字参数
preset
来指定文件的压缩等级。
针对特殊的目的,还存在第二种
mode
格式:
'filemode|[compression]'
。
tarfile.open()
将返回一个将其数据作为数据块流来处理的
TarFile
对象。 对此文件将不能执行随机查找。 如果给定了
fileobj
,它可以是任何具有
read()
或
write()
方法(由
mode
确定)的对象。
bufsize
指定块大小,默认为
20
*
512
字节。 可与此格式组合使用的有
sys.stdin.buffer
、套接字
file object
或磁盘设备等。 但是,这样的
TarFile
对象存在不允许随机访问的限制,参见
例子
。 当前可用的模式有:
'r|*'
打开 tar 块的
流
以进行透明压缩读取。
打开一个未压缩的 tar 块的
stream
用于读取。
'r|gz'
打开一个 gzip 压缩的
stream
用于读取。
'r|bz2'
打开一个 bzip2 压缩的
stream
用于读取。
'r|xz'
打开一个 lzma 压缩
stream
用于读取。
打开一个未压缩的
stream
用于写入。
'w|gz'
打开一个 gzip 压缩的
stream
用于写入。
'w|bz2'
打开一个 bzip2 压缩的
stream
用于写入。
'w|xz'
打开一个 lzma 压缩的
stream
用于写入。
tarfile.
is_tarfile
(
name
)
如果
name
是一个
tarfile
能读取的 tar 归档文件则返回
True
。
name
可以为
str
,文件或文件型对象。
在 3.9 版本发生变更:
支持文件或类文件对象。
tarfile
模块定义了以下异常:
exception
tarfile.
TarError
所有
tarfile
异常的基类。
TarFile 对象
TarFile
对象提供了一个 tar 归档的接口。 一个 tar 归档就是数据块的序列。 一个归档成员(被保存文件)是由一个标头块加多个数据块组成的。 一个文件可以在一个 tar 归档中多次被保存。 每个归档成员都由一个
TarInfo
对象来代表,详情参见
TarInfo 对象
。
TarFile
对象可在
with
语句中作为上下文管理器使用。 当语句块结束时它将自动被关闭。 请注意在发生异常事件时被打开用于写入的归档将不会被终结;只有内部使用的文件对象将被关闭。 相关用例请参见
例子
。
Added in version 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
=
1
,
stream
=
False
)
下列所有参数都是可选项并且也可作为实例属性来访问。
name
是归档的路径名。
name
可以是一个
path-like object
。 如果给定了
fileobj
则它可以被省略。 在此情况下,如果对象存在
name
属性则将使用它。
mode
可以为
'r'
表示从现有归档读取,
'a'
表示将数据追加到现有文件,
'w'
表示创建新文件覆盖现有文件,或者
'x'
表示仅在文件不存在时创建新文件。
如果给定了
fileobj
,它会被用于读取或写入数据。 如果可以被确定,则
mode
会被
fileobj
的模式所覆盖。
fileobj
的使用将从位置 0 开始。
当
TarFile
被关闭时,
fileobj
不会被关闭。
format
控制用于写入的归档格式。 它必须为在模块层级定义的常量
USTAR_FORMAT
,
GNU_FORMAT
或
PAX_FORMAT
中的一个。 当读取时,格式将被自动检测,即使单个归档中存在不同的格式。
tarinfo
参数可以被用来将默认的
TarInfo
类替换为另一个。
如果
dereference
为
False
,则会将符号链接和硬链接添加到归档中。 如果为
True
,则会将目标文件的内容添加到归档中。 在不支持符号链接的系统上参数将不起作用。
如果
ignore_zeros
为
False
,则会将空的数据块当作归档的末尾来处理。 如果为
True
,则会跳过空的(和无效的)数据块并尝试获取尽可能多的成员。 此参数仅适用于读取拼接的或损坏的归档。
debug
可设为从
0
(无调试消息) 到
3
(全部调试消息)。 消息会被写入到
sys.stderr
。
errorlevel
控制如何处理解压错误,参见
相应的属性
。
encoding
和
errors
参数定义了读取或写入归档所使用的字符编码格式以及要如何处理转换错误。 默认设置将适用于大多数用户。 要深入了解详情可参阅
Unicode 问题
小节。
可选的
pax_headers
参数是字符串的字典,如果
format
为
PAX_FORMAT
它将被作为 pax 全局标头被添加。
如果
stream
被设为
True
则在读取时有关归档中文件的归档信息不会被缓存,以节省内存消耗。
在 3.2 版本发生变更:
使用
'surrogateescape'
作为
errors
参数的默认值。
在 3.5 版本发生变更:
添加了
'x'
(单独创建) 模式。
在 3.6 版本发生变更:
name
形参接受一个
path-like object
。
在 3.13 版本发生变更:
增加了
stream
形参。
TarFile.
list
(
verbose
=
True
,
*
,
members
=
None
)
将内容清单打印到
sys.stdout
。 如果
verbose
为
False
,则将只打印成员名称。 如果为
True
,则输出将类似于
ls -l
的输出效果。 如果给定了可选的
members
,它必须为
getmembers()
所返回的列表的一个子集。
在 3.5 版本发生变更:
添加了
members
形参。
TarFile.
extractall
(
path
=
'.'
,
members
=
None
,
*
,
numeric_owner
=
False
,
filter
=
None
)
将归档中的所有成员提取到当前工作目录或
path
目录。 如果给定了可选的
members
,则它必须为
getmembers()
所返回的列表的一个子集。 字典信息例如所有者、修改时间和权限会在所有成员提取完毕后被设置。 这样做是为了避免两个问题:目录的修改时间会在每当在其中创建文件时被重置。 并且如果目录的权限不允许写入,提取文件到目录的操作将失败。
如果
numeric_owner
为
True
,则将使用来自 tarfile 的 uid 和 gid 数值来设置被提取文件的所有者/用户组。 在其他情况下,则会使用来自 tarfile 的名称值。
filter
参数指明在提取之前要如何修改或拒绝
members
。 请参阅
解压缩过滤器
了解详情。 建议应根据你需要支持的
tar
特征显式地设置该参数。
绝不要未经预先检验就从不可靠的源中提取归档文件。 这样有可能在
path
之外创建文件,例如某些成员具有以
"/"
开始的绝对路径文件名或带有两个点号
".."
的文件名。
设置
filter='data'
来防止最危险的安全问题,并请参阅
解压缩过滤器
一节了解详情。section for details.
在 3.5 版本发生变更:
添加了
numeric_owner
形参。
在 3.6 版本发生变更:
path
形参接受一个
path-like object
。
在 3.12 版本发生变更:
添加了
filter
形参。
TarFile.
extract
(
member
,
path
=
''
,
set_attrs
=
True
,
*
,
numeric_owner
=
False
,
filter
=
None
)
从归档中提取出一个成员放入当前工作目录,将使用其完整名称。 成员的文件信息会尽可能精确地被提取。
member
可以是一个文件名或
TarInfo
对象。 你可以使用
path
指定一个不同的目录。
path
可以是一个
path-like object
。 将会设置文件属性 (owner, mtime, mode) 除非
set_attrs
为假值。
numeric_owner
和
filter
参数与
extractall()
中的相同。
extract()
方法不会处理某些提取问题。 在大多数情况下你应当考虑使用
extractall()
方法。
查看
extractall()
的警告信息。
设置
filter='data'
来防止最危险的安全问题,并请参阅
解压缩过滤器
一节了解详情。section for details.
在 3.2 版本发生变更:
添加了
set_attrs
形参。
在 3.5 版本发生变更:
添加了
numeric_owner
形参。
在 3.6 版本发生变更:
path
形参接受一个
path-like object
。
在 3.12 版本发生变更:
添加了
filter
形参。
TarFile.
extractfile
(
member
)
将归档中的一个成员提取为文件对象。
member
可以是一个文件名或
TarInfo
对象。 如果
member
是一个常规文件或链接,则会返回一个
io.BufferedReader
对象。 对于所有其他现有成员,则都将返回
None
。 如果
member
未在归档中出现,则会引发
KeyError
。
在 3.3 版本发生变更:
返回一个
io.BufferedReader
对象。
在 3.13 版本发生变更:
返回的
io.BufferedReader
对象具有
mode
属性并且总是会等于
'rb'
。
TarFile.
errorlevel
:
int
如果
errorlevel
为
0
,则在使用
TarFile.extract()
和
TarFile.extractall()
时错误会被忽略。 不过,当
debug
大于 0 时它们将会作为错误消息在调试输出中出现。 如果
errorlevel*为 ``1`` (默认值),则所有 *fatal
错误都会作为
OSError
或
FilterError
异常被引发。 如果为
2
,则所有
non-fatal
错误也会作为
TarError
异常被引发。
某些异常,如参数类型错误或数据损坏导致的异常,总是会被触发。
自定义
提取过滤器
应针对
fatal
错误引发
FilterError
,针对
non-fatal
错误引发
ExtractError
。
请注意,当出现异常时,存档可能会被部分提取。用需要户负责进行清理。
被用作
extract()
和
extractall()
的
filter
参数的默认值的
提取过滤器
。
该属性可以为
None
或是一个可调用对象。 与
extract()
的
filter
参数不同,该属性不允许使用字符串名称。
如果
extraction_filter
为
None
(默认值),则不带
filter
参数调用提取方法将引发
DeprecationWarning
,并回退至
fully_trusted
过滤器,其危险行为与之前版本的 Python 一致。
在 Python 3.14+ 中,保持
extraction_filter=None
将导致提取方法默认使用
data
过滤器。
该属性可在实例上设置或在子类中覆盖。 也可以在
TarFile
类本身上设置它以设置一个全局默认值,不过,由于它会影响
tarfile
的所有使用,最好的做法是只在最高层级应和程序或
站点配置
中这样做。 要以这种方式设置全局默认值,需要将一个过滤器函数包装在
staticmethod()
中以防止
self
参数的注入。
TarFile.
add
(
name
,
arcname
=
None
,
recursive
=
True
,
*
,
filter
=
None
)
将文件
name
添加到归档。
name
可以为任意类型的文件(目录、fifo、符号链接等等)。 如果给出
arcname
则它将为归档中的文件指定一个替代名称。 默认情况下会递归地添加目录。 这可以通过将
recursive
设为
False
来避免。 递归操作会按排序顺序添加条目。 如果给定了
filter
,它应当为一个接受
TarInfo
对象并返回已修改
TarInfo
对象的函数。 如果它返回
None
则
TarInfo
对象将从归档中被排除。 具体示例参见
例子
。
在 3.2 版本发生变更:
添加了
filter
形参。
在 3.7 版本发生变更:
递归操作按排序顺序添加条目。
TarFile.
addfile
(
tarinfo
,
fileobj
=
None
)
将
TarInfo
对象
tarinfo
添加到归档中。 如果
tarinfo
代表一个大小不为零的常规文件,则
fileobj
参数应为一个
binary file
,且会从中读取
tarinfo.size
个字节并添加到归档中。 你可以直接创建
TarInfo
对象,或者也可以使用
gettarinfo()
。
在 3.13 版本发生变更:
对于大小不为零的常规文件必须给出
fileobj
。
TarFile.
gettarinfo
(
name
=
None
,
arcname
=
None
,
fileobj
=
None
)
基于
os.stat()
的结果或者现有文件的相同数据创建一个
TarInfo
。 文件或者是命名为
name
,或者是使用文件描述符指定为一个
file object
fileobj
。
name
可以是一个
path-like object
。 如果给定了
arcname
,则它将为归档中的文件指定一个替代名称,在其他情况下,名称将从
fileobj
的
name
属性或
name
参数获取。 名称应当是一个文本字符串。
你可以在使用
addfile()
添加
TarInfo
的某些属性之前修改它们。 如果文件对象不是从文件开头进行定位的普通文件对象,
size
之类的属性就可能需要修改。 例如
GzipFile
之类的文件就属于这种情况。
name
也可以被修改,在这种情况下
arcname
可以是一个占位字符串。
在 3.6 版本发生变更:
name
形参接受一个
path-like object
。
TarInfo 对象
TarInfo
对象代表
TarFile
中的一个文件。 除了会存储所有必要的文件属性(例如文件类型、大小、时间、权限、所有者等),它还提供了一些确定文件类型的有用方法。 此对象
并不
包含文件数据本身。
TarInfo
对象可通过
TarFile
的方法
getmember()
,
getmembers()
和
gettarinfo()
返回。
修改
getmember()
或
getmembers()
返回的对象会影响在上的所有后续操作。 对于不想要这样的场景,你可以使用
copy.copy()
或调用
replace()
方法一次性创建修改后的副本。
部分属性可以设为
None
以表示一些元数据未被使用或未知。 不同的
TarInfo
方法会以不同的方式处理
None
:
extract()
或
extractall()
方法会忽略相应的元数据,让其保持默认设置。
addfile()
将会失败。
list()
将打印一个占位字符串。
class
tarfile.
TarInfo
(
name
=
''
)
创建一个
TarInfo
对象。
classmethod
TarInfo.
frombuf
(
buf
,
encoding
,
errors
)
基于字符串缓冲区
buf
创建并返回一个
TarInfo
对象。
如果缓冲区无效则会引发
HeaderError
。
TarInfo.
tobuf
(
format
=
DEFAULT_FORMAT
,
encoding
=
ENCODING
,
errors
=
'surrogateescape'
)
基于
TarInfo
对象创建一个字符串缓冲区。 有关参数的信息请参见
TarFile
类的构造器。
在 3.2 版本发生变更:
使用
'surrogateescape'
作为
errors
参数的默认值。
TarInfo
对象具有以下公有数据属性:
TarInfo.
name
:
str
归档成员的名称。
TarInfo.
replace
(
name
=
...
,
mtime
=
...
,
mode
=
...
,
linkname
=
...
,
uid
=
...
,
gid
=
...
,
uname
=
...
,
gname
=
...
,
deep
=
True
)
Added in version 3.12.
返回修改了给定属性的
TarInfo
对象的
新
副本。 例如,要返回组名设为
'staff'
的
TarInfo
,请使用:
new_tarinfo
= old_tarinfo.replace(gname='staff')
在默认情况下,将执行深拷贝。 如果 deep 为假值,则执行浅拷贝,即 pax_headers
及任何自定义属性都与原始 TarInfo
对象共享。
TarInfo
对象还提供了一些便捷查询方法:
TarInfo.isfile()
如果 TarInfo
对象为普通文件则返回 True
。
Added in version 3.12.
tar 格式的设计旨在捕捉类 UNIX 文件系统的所有细节,这使其功能非常强大。 不幸的是,这些特性也使得很容易创建在解压缩时产生意想不到的 -- 甚至可能是恶意的 -- 影响的 tar 文件。 举例来说,解压缩 tar 文件时可以通过各种方式覆盖任意文件(例如通过使用绝对路径、..
路径组件或影响后续成员的符号链接等)。
在大多数情况下,并不需要全部的功能。 因此,tarfile 支持提取过滤器:一种限制功能的机制,从而避免一些安全问题。
PEP 706包含设计背后进一步的动机和理由。
TarFile.extract()
或 extractall()
的 filter 参数可以是:
字符串 'fully_trusted'
:尊重归档文件中指定的所有元数据。 如果用户完全信任该归档,或实现了自己的复杂验证则应使用此过滤器。
字符串 'tar'
: 尊重大多数 tar 专属的特性(即类 UNIX 文件系统的功能),但阻止极有可能令人惊讶的或恶意的功能。 详情参见 tar_filter()
。
字符串 'data'
:忽略或阻止大多数类 UNIX 文件系统专属的特性。 用于提取跨平台数据归档文件。 详情参见 data_filter()
。
None
(默认): 使用 TarFile.extraction_filter
。
如果这也为 None
(默认值),则引发 DeprecationWarning
,并回退为 'fully_trusted'
过滤器,其危险行为与之前版本的 Python 一致。
在 Python 3.14 中,'data'
过滤器将变成默认选项。 也可以提前切换,参见 TarFile.extraction_filter
。
该可调用对象将针每个被提取的成员执行调用并附带一个 TarInfo 来描述该成员以及被提取归档文件的目标路径(即供所有成员使用的相同路径):