You are here:  Home » Python » tarfile读取和写入tar归档文件(6)Python数据压缩和存档(必读进阶Python教程)(参考资料)

tarfile模块可以读取和写入tar档案,包括使用gzip,bz2和lzma压缩的档案。使用该zipfile模块读取或写入.zip文件,或shutil中的更高级别的功能。

一些事实和数据:

  • 如果相应的模块可用gzip,则读取和写入bz2以及lzma压缩存档。
  • 对POSIX.1-1988(ustar)格式的读/写支持。
  • 对GNU tar格式的读/写支持,包括longnamelonglink 扩展,对稀疏扩展的所有变体的只读支持,包括稀疏文件的恢复。
  • 对POSIX.1-2001(pax)格式的读/写支持。
  • 处理目录,常规文件,硬链接,符号链接,fifos,字符设备和块设备,并能够获取和恢复文件信息,如时间戳,访问权限和所有者。

版本3.3中已更改:添加了对lzma压缩的支持。

tarfile.openname = Nonemode =’r’fileobj = Nonebufsize = 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 * 512sys.stdinTarFile

模式 行动
'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.TarFilename = Nonemode =’r’fileobj = Noneformat = DEFAULT_FORMATtarinfo = TarInfodereference = Falseignore_zeros = Falseencoding = ENCODINGerrors =’surrogateescape’pax_headers = Nonedebug = 0errorlevel = 0 
以下所有参数都是可选的,也可以作为实例属性进行访问。

name是存档的路径名。name可以是类似路径的对象。如果给出了fileobj,则可以省略它。在这种情况下,如果文件对象的name属性存在,则使用该属性。

mode'r'从现有存档读取,'a'将数据附加到现有文件,'w'创建覆盖现有文件的新文件,或'x'仅在新文件尚不存在时创建新文件。

如果给出了fileobj,则它用于读取或写入数据。如果可以确定,则fileobj模式会覆盖模式。fileobj将从位置0使用。

注意

关闭时,fileobjTarFile关闭。

format控制存档格式。它必须是常量之一 USTAR_FORMATGNU_FORMAT或者PAX_FORMAT在模块级别定义。

tarinfo参数可以用来替换缺省TarInfo使用不同的一类。

如果取消引用False,加符号和硬链接到存档。如果是True,请将目标文件的内容添加到存档中。这对不支持符号链接的系统没有影响。

如果ignore_zerosFalse则将空块视为存档的结尾。如果是True,则跳过空(和无效)块并尝试获得尽可能多的成员。这仅适用于读取连锁或损坏的档案。

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

如果是errorlevel0,则在使用时会忽略所有错误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.listverbose = True*members = None 
打印目录到sys.stdout。如果是详细False,则仅打印成员的名称。如果是True,则产生类似于ls -l的输出。如果给出了可选成员,则它必须是返回的列表的子集getmembers()

在3.5版中更改:添加了members参数。

TarFile.next
将打开的下一个成员作为TarInfo对象返回, TarFile打开后进行读取。None如果没有更多可用,请返回。
TarFile.extractallpath =“。”members = None*numeric_owner = False 
将存档中的所有成员解压缩到当前工作目录或目录路径。如果给出了可选成员,则它必须是返回的列表的子集getmembers()。提取所有成员后,将设置所有者,修改时间和权限等目录信息。这样做是为了解决两个问题:每次在其中创建文件时,都会重置目录的修改时间。并且,如果目录的权限不允许写入,则向其提取文件将失败。

如果numeric_ownerTrue,从tar文件的UID和GID数字用于设置所有者/组为所提取的文件。否则,使用tarfile中的命名值。

警告

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

在3.5版中更改:添加了numeric_owner参数。

改变在3.6版本:路径参数接受路径状物体

TarFile.extractmemberpath =“”set_attrs = True*numeric_owner = False 
使用其全名将成员从存档中提取到当前工作目录。其文件信息尽可能准确地提取。member 可以是文件名或TarInfo对象。您可以使用path指定其他目录。路径可以是类似路径的对象。除非set_attrs为false,否则将设置文件属性(所有者,mtime,模式)。

如果numeric_ownerTrue,从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.addnamearcname = Nonerecursive = True*filter = None 
将文件添加到存档。name可以是任何类型的文件(目录,fifo,符号链接等)。如果给定,arcname指定归档中文件的备用名称。默认情况下递归添加目录。这可以通过设置递归来 避免False。递归按排序顺序添加条目。如果给出了filter,它应该是一个带有TarInfoobject参数并返回已更改TarInfo对象的函数。如果它返回,NoneTarInfo对象将从存档中排除。有关示例,请参见示例。

版本3.2中已更改:添加了过滤器参数。

版本3.7中已更改:递归按排序顺序添加条目。

TarFile.addfiletarinfofileobj =无
TarInfo对象tarinfo添加到存档。如果给出了fileobj,它应该是一个二进制文件,并 tarinfo.size从中读取字节并将其添加到存档中。您可以TarInfo直接创建对象,也可以使用gettarinfo()
TarFile.gettarinfoname = Nonearcname = Nonefileobj = None 
TarInfoos.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.TarInfoname =“” 
创建一个TarInfo对象。
classmethod TarInfo.frombufbuf编码错误
TarInfo从字符串缓冲区buf创建并返回一个对象。

HeaderError如果缓冲区无效则引发。

classmethod TarInfo.fromtarfiletarfile 
TarFile对象tarfile中读取下一个成员并将其作为TarInfo对象返回。
TarInfo.tobufformat = DEFAULT_FORMATencoding = ENCODINGerrors =’surrogateescape’ 
TarInfo对象创建字符串缓冲区。有关参数的信息,请参阅TarFile类的构造函数。

在3.2版本中更改:使用'surrogateescape'作为默认的错误说法。

一个TarInfo对象有下列公共数据属性:

TarInfo.name
存档成员的名称。
TarInfo.size
大小以字节为单位
TarInfo.mtime
最后修改的时间。
TarInfo.mode
权限位。
TarInfo.type
文件类型。 类型通常是这些常量之一:REGTYPE, AREGTYPELNKTYPESYMTYPEDIRTYPE, FIFOTYPECONTTYPECHRTYPEBLKTYPE, 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

命令行选项

-l <tarfile>
--list <tarfile>
列出tarfile中的文件。
-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由类的encodingerrors关键字参数控制 TarFile

encoding定义用于存档中元数据的字符编码。默认值是sys.getfilesystemencoding()'ascii' 作为后备。根据是读取还是写入存档,必须对元数据进行解码或编码。如果未正确设置编码,则此转换可能会失败。

所述误差参数定义字符被如何处理不能被转换。错误处理程序一节中列出了可能的值。默认方案是'surrogateescape'Python也用于其文件系统调用,请参阅文件名,命令行参数和环境变量

PAX_FORMAT存档的情况下,通常不需要编码,因为所有元数据都使用UTF-8存储。编码仅用于解码二进制pax标头或存储具有代理项字符的字符串的极少数情况。