tarfile读取和写入tar归档文件(6)Python数据压缩和存档(必读进阶Python教程)(参考资料)
该tarfile
模块可以读取和写入tar档案,包括使用gzip,bz2和lzma压缩的档案。使用该zipfile
模块读取或写入.zip
文件,或shutil中的更高级别的功能。
一些事实和数据:
- 如果相应的模块可用
gzip
,则读取和写入bz2
以及lzma
压缩存档。 - 对POSIX.1-1988(ustar)格式的读/写支持。
- 对GNU tar格式的读/写支持,包括longname和longlink 扩展,对稀疏扩展的所有变体的只读支持,包括稀疏文件的恢复。
- 对POSIX.1-2001(pax)格式的读/写支持。
- 处理目录,常规文件,硬链接,符号链接,fifos,字符设备和块设备,并能够获取和恢复文件信息,如时间戳,访问权限和所有者。
版本3.3中已更改:添加了对lzma
压缩的支持。
tarfile.
open
(name = None,mode =’r’,fileobj = None,bufsize = 10240,** kwargs )- 返回
TarFile
路径名称的对象。有关TarFile
对象和允许的关键字参数的详细信息,请参阅TarFile对象。mode必须是表单的字符串
'filemode[:compression]'
,默认为'r'
。以下是模式组合的完整列表:模式 行动 'r' or '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' or 'a:'
打开以便在没有压缩的情况下追加。如果文件不存在,则创建该文件。 'w' or 'w:'
打开无压缩写作。 'w:gz'
打开gzip压缩写入。 'w:bz2'
打开bzip2压缩写入。 'w:xz'
打开lzma压缩写入。 请注意
'a:gz'
,'a:bz2'
或者'a:xz'
不可能。如果模式 不适合打开某个(压缩)文件进行读取,ReadError
则引发该模式。使用模式'r'
来避免这种情况。如果不支持压缩方法,CompressionError
则引发该方法。如果指定了fileobj,则它将用作替换以 二进制模式为name打开的文件对象。它应该在0位置。
对于模式
'w:gz'
,'r:gz'
,'w:bz2'
,'r:bz2'
,'x:gz'
,'x:bz2'
,tarfile.open()
接受关键字参数compresslevel(默认9
)来指定该文件的压缩级别。出于特殊目的,模式有第二种格式:
'filemode|[compression]'
。tarfile.open()
将返回一个TarFile
对象,该对象将其数据作为块流进行处理。不会对文件进行随机搜索。如果给定,fileobj可以是具有read()
或write()
方法的任何对象 (取决于模式)。bufsize 指定块大小,默认为字节。将此变体与例如套接字文件对象或磁带设备结合使用。但是,这样的对象受到限制,因为它不允许随机访问,参见示例。目前可能的模式:20 * 512
sys.stdin
TarFile
模式 行动 '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'
加入(独家创作)模式。改变在3.6版本:该名称参数接受路径状物体。
- 类
tarfile.
TarFile
- 用于读写tar档案的类。不要直接使用此类:请
tarfile.open()
改用。请参见TarFile对象。
tarfile.
is_tarfile
(名字)True
如果name是tar存档文件,则返回该tarfile
模块可以读取的文件。
该tarfile
模块定义了以下例外:
- 异常
tarfile.
TarError
- 所有
tarfile
例外的基类。
- 异常
tarfile.
ReadError
- 在打开tar存档时引发,该
tarfile
模块无法由模块处理 或以某种方式无效。
- 异常
tarfile.
CompressionError
- 在不支持压缩方法或无法正确解码数据时引发。
- 异常
tarfile.
StreamError
- 针对流类
TarFile
对象的典型限制而提出。
- 异常
tarfile.
ExtractError
- 使用时会引发非致命错误
TarFile.extract()
,但仅限于 。TarFile.errorlevel
== 2
- 异常
tarfile.
HeaderError
TarInfo.frombuf()
如果它获得的缓冲区无效则引发。
模块级别提供以下常量:
tarfile.
ENCODING
- 默认字符编码:
'utf-8'
在Windows上,sys.getfilesystemencoding()
否则返回的值 。
以下每个常量都定义了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
- 创建存档的默认格式。这是目前的
GNU_FORMAT
。
也可以看看
- 模
zipfile
zipfile
标准模块的文档。- 归档操作
- 标准
shutil
模块提供的高级归档设施的文档。 - GNU tar手册,基本焦油格式
- tar归档文件的文档,包括GNU tar扩展。
TarFile对象
该TarFile
对象提供了tar存档的接口。tar存档是一系列块。归档成员(存储文件)由标题块后跟数据块组成。可以将文件多次存储在tar存档中。每个归档成员都由一个TarInfo
对象表示,有关详细信息,请参阅TarInfo对象。
一个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可以是类似路径的对象。如果给出了fileobj,则可以省略它。在这种情况下,如果文件对象的
name
属性存在,则使用该属性。mode是
'r'
从现有存档读取,'a'
将数据附加到现有文件,'w'
创建覆盖现有文件的新文件,或'x'
仅在新文件尚不存在时创建新文件。如果给出了fileobj,则它用于读取或写入数据。如果可以确定,则fileobj的模式会覆盖模式。fileobj将从位置0使用。
注意
关闭时,fileobj未
TarFile
关闭。format控制存档格式。它必须是常量之一
USTAR_FORMAT
,GNU_FORMAT
或者PAX_FORMAT
在模块级别定义。该tarinfo参数可以用来替换缺省
TarInfo
使用不同的一类。如果取消引用是
False
,加符号和硬链接到存档。如果是True
,请将目标文件的内容添加到存档中。这对不支持符号链接的系统没有影响。如果ignore_zeros是
False
,则将空块视为存档的结尾。如果是True
,则跳过空(和无效)块并尝试获得尽可能多的成员。这仅适用于读取连锁或损坏的档案。debug可以从
0
(无调试消息)到3
(所有调试消息)设置。邮件被写入sys.stderr
。如果是errorlevel
0
,则在使用时会忽略所有错误TarFile.extract()
。然而,当启用调试时,它们在调试输出中显示为错误消息。如果1
,所有致命错误都是OSError
异常引发的。如果2
,所有非致命错误也会引发TarError
异常。该编码和错误参数定义用于读取或写入档案,以及如何转换错误将要处理的字符编码。默认设置适用于大多数用户。有关详细信息,请参阅Unicode问题部分。
所述pax_headers参数是将要添加作为PAX全局头如果串的一个可选的字典的格式是
PAX_FORMAT
。在3.2版本中更改:使用
'surrogateescape'
作为默认的错误说法。改变在3.5版本:将
'x'
加入(独家创作)模式。改变在3.6版本:该名称参数接受路径状物体。
- classmethod
TarFile.
open
(… ) - 替代构造函数。该
tarfile.open()
函数实际上是此类方法的快捷方式。
TarFile.
getmember
(名字)- 返回
TarInfo
成员名称的对象。如果在归档中找不到名称,KeyError
则引发。注意
如果成员在归档中出现多次,则其最后一次出现将被假定为最新版本。
TarFile.
getmembers
()- 将归档的成员作为
TarInfo
对象列表返回。该列表与归档中的成员具有相同的顺序。
TarFile.
getnames
()- 将成员作为名称列表返回。它与返回的列表具有相同的顺序
getmembers()
。
TarFile.
list
(verbose = True,*,members = None )- 打印目录到
sys.stdout
。如果是详细的False
,则仅打印成员的名称。如果是True
,则产生类似于ls -l的输出。如果给出了可选成员,则它必须是返回的列表的子集getmembers()
。在3.5版中更改:添加了members参数。
TarFile.
next
()- 将打开的下一个成员作为
TarInfo
对象返回,TarFile
打开后进行读取。None
如果没有更多可用,请返回。
TarFile.
extractall
(path =“。”,members = None,*,numeric_owner = False )- 将存档中的所有成员解压缩到当前工作目录或目录路径。如果给出了可选成员,则它必须是返回的列表的子集
getmembers()
。提取所有成员后,将设置所有者,修改时间和权限等目录信息。这样做是为了解决两个问题:每次在其中创建文件时,都会重置目录的修改时间。并且,如果目录的权限不允许写入,则向其提取文件将失败。如果numeric_owner是
True
,从tar文件的UID和GID数字用于设置所有者/组为所提取的文件。否则,使用tarfile中的命名值。警告
未经事先检查,切勿从不受信任的来源提取档案。文件可能在路径之外创建,例如,具有
"/"
以两个点开头的绝对文件名或具有两个点的文件名的成员".."
。在3.5版中更改:添加了numeric_owner参数。
改变在3.6版本:该路径参数接受路径状物体。
TarFile.
extract
(member,path =“”,set_attrs = True,*,numeric_owner = False )- 使用其全名将成员从存档中提取到当前工作目录。其文件信息尽可能准确地提取。member 可以是文件名或
TarInfo
对象。您可以使用path指定其他目录。路径可以是类似路径的对象。除非set_attrs为false,否则将设置文件属性(所有者,mtime,模式)。如果numeric_owner是
True
,从tar文件的UID和GID数字用于设置所有者/组为所提取的文件。否则,使用tarfile中的命名值。注意
该
extract()
方法不处理几个提取问题。在大多数情况下,您应该考虑使用该extractall()
方法。警告
请参阅警告
extractall()
。版本3.2中已更改:添加了set_attrs参数。
在3.5版中更改:添加了numeric_owner参数。
改变在3.6版本:该路径参数接受路径状物体。
TarFile.
extractfile
(会员)- 从存档中提取成员作为文件对象。member可以是文件名或
TarInfo
对象。如果member是常规文件或链接,io.BufferedReader
则返回一个 对象。否则,None
返回。在版本3.3中更改:返回一个
io.BufferedReader
对象。
TarFile.
add
(name,arcname = None,recursive = True,*,filter = None )- 将文件名添加到存档。name可以是任何类型的文件(目录,fifo,符号链接等)。如果给定,arcname指定归档中文件的备用名称。默认情况下递归添加目录。这可以通过设置递归来 避免
False
。递归按排序顺序添加条目。如果给出了filter,它应该是一个带有TarInfo
object参数并返回已更改TarInfo
对象的函数。如果它返回,None
则TarInfo
对象将从存档中排除。有关示例,请参见示例。版本3.2中已更改:添加了过滤器参数。
版本3.7中已更改:递归按排序顺序添加条目。
TarFile.
addfile
(tarinfo,fileobj =无)- 将
TarInfo
对象tarinfo添加到存档。如果给出了fileobj,它应该是一个二进制文件,并tarinfo.size
从中读取字节并将其添加到存档中。您可以TarInfo
直接创建对象,也可以使用gettarinfo()
。
TarFile.
gettarinfo
(name = None,arcname = None,fileobj = None )TarInfo
从os.stat()
现有文件的结果或等效项创建对象。该文件可以按名称命名,也可以指定为带有文件描述符的文件对象 fileobj。 name可以是类似路径的对象。如果给定,arcname为归档中的文件指定备用名称,否则,名称取自fileobj的name
属性或name参数。名称应该是文本字符串。您可以
TarInfo
在使用之前修改某些属性addfile()
。如果文件对象不是位于文件开头的普通文件对象,则size
可能需要修改属性。对象就是这种情况GzipFile
。的name
也可以被修饰,在这种情况下arcname 可能是一个虚设字符串。改变在3.6版本:该名称参数接受路径状物体。
TarFile.
close
()- 关闭
TarFile
。在写入模式下,两个完成零块将附加到存档。
TarFile.
pax_headers
- 包含pax全局标头的键值对的字典。
TarInfo对象
一个TarInfo
对象代表一个成员TarFile
。除了存储文件的所有必需属性(如文件类型,大小,时间,权限,所有者等)之外,它还提供了一些有用的方法来确定其类型。它不包含该文件的数据本身。
TarInfo
对象由TarFile
方法 返回getmember()
,getmembers()
和gettarinfo()
。
- class
tarfile.
TarInfo
(name =“” ) - 创建一个
TarInfo
对象。
- classmethod
TarInfo.
frombuf
(buf,编码,错误) TarInfo
从字符串缓冲区buf创建并返回一个对象。HeaderError
如果缓冲区无效则引发。
- classmethod
TarInfo.
fromtarfile
(tarfile ) - 从
TarFile
对象tarfile中读取下一个成员并将其作为TarInfo
对象返回。
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.
linkname
- 目标文件名的名称,仅出现在
TarInfo
类型LNKTYPE
和的对象中SYMTYPE
。
TarInfo.
uid
- 最初存储此成员的用户的用户标识。
TarInfo.
gid
- 最初存储此成员的用户的组ID。
TarInfo.
uname
- 用户名。
TarInfo.
gname
- 团队名字。
TarInfo.
pax_headers
- 包含关联的pax扩展头的键值对的字典。
一个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
如果是FIFO,则返回。
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
命令行选项
-c
<tarfile> <source1> ... <sourceN>
--create
<tarfile> <source1> ... <sourceN>
- 从源文件创建tarfile。
-e
<tarfile> [<output_dir>]
--extract
<tarfile> [<output_dir>]
- 如果未指定output_dir,则将tarfile解压缩到当前目录中。
-t
<tarfile>
--test
<tarfile>
- 测试tarfile是否有效。
-v
,
--verbose
- 详细输出。
示例
如何将整个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()
支持的tar格式
可以使用该tarfile
模块创建三种tar格式:
-
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格式的变体,但不兼容。
Unicode问题
tar格式最初被设想为在磁带驱动器上进行备份,主要侧重于保留文件系统信息。如今,tar档案通常用于文件分发和通过网络交换档案。原始格式(所有其他格式的基础)的一个问题是没有支持不同字符编码的概念。例如,如果包含非ASCII,则在Latin-1系统上无法正确读取在UTF-8系统上创建的普通tar存档字符。文本元数据(如文件名,链接名,用户/组名)将显示已损坏。不幸的是,没有办法自动检测存档的编码。pax格式旨在解决此问题。它使用通用字符编码UTF-8存储非ASCII元数据。
字符转换的细节tarfile
由类的encoding和errors关键字参数控制 TarFile
。
encoding定义用于存档中元数据的字符编码。默认值是sys.getfilesystemencoding()
或'ascii'
作为后备。根据是读取还是写入存档,必须对元数据进行解码或编码。如果未正确设置编码,则此转换可能会失败。
所述误差参数定义字符被如何处理不能被转换。错误处理程序一节中列出了可能的值。默认方案是'surrogateescape'
Python也用于其文件系统调用,请参阅文件名,命令行参数和环境变量。
在PAX_FORMAT
存档的情况下,通常不需要编码,因为所有元数据都使用UTF-8存储。编码仅用于解码二进制pax标头或存储具有代理项字符的字符串的极少数情况。