tarfile --- 讀寫(xiě)tar歸檔文件?

源代碼: Lib/tarfile.py


tarfile 模塊可以用來(lái)讀寫(xiě) tar 歸檔,包括使用 gzip, bz2 和 lzma 壓縮的歸檔。 請使用 zipfile 模塊來(lái)讀寫(xiě) .zip 文件,或者使用 shutil 的高層級函數。

一些事實(shí)和數字:

  • 讀寫(xiě) gzip, bz2lzma 解壓的歸檔要求相應的模塊可用。

  • 支持讀取 / 寫(xiě)入 POSIX.1-1988 (ustar) 格式。

  • 對 GNU tar 格式的讀/寫(xiě)支持,包括 longnamelonglink 擴展,對所有種類(lèi) sparse 擴展的只讀支持,包括 sparse 文件的恢復。

  • 對 POSIX.1-2001 (pax) 格式的讀/寫(xiě)支持。

  • 處理目錄、正常文件、硬鏈接、符號鏈接、fifo 管道、字符設備和塊設備,并且能夠獲取和恢復文件信息例如時(shí)間戳、訪(fǎng)問(wèn)權限和所有者等。

在 3.3 版更改: 添加了對 lzma 壓縮的支持。

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)?

針對路徑名 name 返回 TarFile 對象。 有關(guān) TarFile 對象以及所允許的關(guān)鍵字參數的詳細信息請參閱 TarFile 對象。

mode 必須是 'filemode[:compression]' 形式的字符串,其默認值為 'r'。 以下是模式組合的完整列表:

模式

action

'r' or 'r:*'

打開(kāi)和讀取使用透明壓縮(推薦)。

'r:'

打開(kāi)和讀取不使用壓縮。

'r:gz'

打開(kāi)和讀取使用gzip 壓縮。

'r:bz2'

打開(kāi)和讀取使用bzip2 壓縮。

'r:xz'

打開(kāi)和讀取使用lzma 壓縮。

'x''x:'

Create a tarfile exclusively without compression. Raise a FileExistsError exception if it already exists.

'x:gz'

Create a tarfile with gzip compression. Raise a FileExistsError exception if it already exists.

'x:bz2'

Create a tarfile with bzip2 compression. Raise a FileExistsError exception if it already exists.

'x:xz'

Create a tarfile with lzma compression. Raise a FileExistsError exception if it already exists.

'a' or 'a:'

打開(kāi)以便在沒(méi)有壓縮的情況下追加。如果文件不存在,則創(chuàng )建該文件。

'w' or 'w:'

打開(kāi)用于未壓縮的寫(xiě)入。

'w:gz'

打開(kāi)用于 gzip 壓縮的寫(xiě)入。

'w:bz2'

打開(kāi)用于 bzip2 壓縮的寫(xiě)入。

'w:xz'

打開(kāi)用于 lzma 壓縮的寫(xiě)入。

請注意 'a:gz', 'a:bz2''a:xz' 是不可能的組合。 如果 mode 不適用于打開(kāi)特定(壓縮的)文件用于讀取,則會(huì )引發(fā) ReadError。 請使用 mode 'r' 來(lái)避免這種情況。 如果某種壓縮方法不受支持,則會(huì )引發(fā) CompressionError。

如果指定了 fileobj,它會(huì )被用作對應于 name 的以二進(jìn)制模式打開(kāi)的 file object 的替代。 它會(huì )被設定為處在位置 0。

對于 'w:gz', 'r:gz', 'w:bz2', 'r:bz2', 'x:gz', 'x:bz2' 等模式,tarfile.open() 接受關(guān)鍵字參數 compresslevel (默認值為 9) 來(lái)指定文件的壓縮等級。

對于 'w:xz''x:xz' 模式,tarfile.open() 接受關(guān)鍵字參數 preset 來(lái)指定文件的壓縮等級。

針對特殊的目的,還存在第二種 mode 格式: 'filemode|[compression]'。 tarfile.open() 將返回一個(gè)將其數據作為數據塊流來(lái)處理的 TarFile 對象。 對此文件將不能執行隨機查找。 如果給定了 fileobj,它可以是任何具有 read()write() 方法 (由 mode 確定) 的對象。 bufsize 指定塊大小,默認值為 20 * 512 字節。 可與此格式組合使用的有 sys.stdin, 套接字 file object 或磁帶設備等。 但是,對于這樣的 TarFile 對象存在不允許隨機訪(fǎng)問(wèn)的限制,參見(jiàn) 例子。 目前可用的模式如下:

模式

動(dòng)作

'r|*'

打開(kāi) tar 塊的 以進(jìn)行透明壓縮讀取。

'r|'

打開(kāi)一個(gè)未壓縮的 tar 塊的 stream 用于讀取。

'r|gz'

打開(kāi)一個(gè) gzip 壓縮的 stream 用于讀取。

'r|bz2'

打開(kāi)一個(gè) bzip2 壓縮的 stream 用于讀取。

'r|xz'

打開(kāi)一個(gè) lzma 壓縮 stream 用于讀取。

'w|'

打開(kāi)一個(gè)未壓縮的 stream 用于寫(xiě)入。

'w|gz'

打開(kāi)一個(gè) gzip 壓縮的 stream 用于寫(xiě)入。

'w|bz2'

打開(kāi)一個(gè) bzip2 壓縮的 stream 用于寫(xiě)入。

'w|xz'

打開(kāi)一個(gè) lzma 壓縮的 stream 用于寫(xiě)入。

在 3.5 版更改: 添加了 'x' (單獨創(chuàng )建) 模式。

在 3.6 版更改: name 形參接受一個(gè) path-like object。

class tarfile.TarFile

用于讀取和寫(xiě)入 tar 歸檔的類(lèi)。 請不要直接使用這個(gè)類(lèi):而要使用 tarfile.open()。 參見(jiàn) TarFile 對象。

tarfile.is_tarfile(name)?

如果 name 是一個(gè) tarfile 能讀取的 tar 歸檔文件則返回 True。 name 可以為 str,文件或文件類(lèi)對象。

在 3.9 版更改: 支持文件或類(lèi)文件對象。

tarfile 模塊定義了以下異常:

exception tarfile.TarError?

所有 tarfile 異常的基類(lèi)。

exception tarfile.ReadError?

當一個(gè)不能被 tarfile 模塊處理或者因某種原因而無(wú)效的 tar 歸檔被打開(kāi)時(shí)將被引發(fā)。

exception tarfile.CompressionError?

當一個(gè)壓縮方法不受支持或者當數據無(wú)法被正確解碼時(shí)將被引發(fā)。

exception tarfile.StreamError?

當達到流式 TarFile 對象的典型限制時(shí)將被引發(fā)。

exception tarfile.ExtractError?

當使用 TarFile.extract() 時(shí)針對 non-fatal 所引發(fā)的異常,但是僅限 TarFile.errorlevel== 2。

exception tarfile.HeaderError?

如果獲取的緩沖區無(wú)效則會(huì )由 TarInfo.frombuf() 引發(fā)的異常。

以下常量在模塊層級上可用:

tarfile.ENCODING?

默認的字符編碼格式:在 Windows 上為 'utf-8',其他系統上則為 sys.getfilesystemencoding() 所返回的值。

以下常量各自定義了一個(gè) tarfile 模塊能夠創(chuàng )建的 tar 歸檔格式。 相關(guān)細節請參閱 受支持的 tar 格式 小節。

tarfile.USTAR_FORMAT?

POSIX.1-1988 (ustar) 格式。

tarfile.GNU_FORMAT?

GNU tar 格式。

tarfile.PAX_FORMAT?

POSIX.1-2001 (pax) 格式。

tarfile.DEFAULT_FORMAT?

用于創(chuàng )建歸檔的默認格式。 目前為 PAX_FORMAT。

在 3.8 版更改: 新歸檔的默認格式已更改為 PAX_FORMAT 而不再是 GNU_FORMAT。

參見(jiàn)

模塊 zipfile

zipfile 標準模塊的文檔。

歸檔操作

標準 shutil 模塊所提供的高層級歸檔工具的文檔。

GNU tar manual, Basic Tar Format

針對 tar 歸檔文件的文檔,包含 GNU tar 擴展。

TarFile 對象?

TarFile 對象提供了一個(gè) tar 歸檔的接口。 一個(gè) tar 歸檔就是數據塊的序列。 一個(gè)歸檔成員(被保存文件)是由一個(gè)標頭塊加多個(gè)數據塊組成的。 一個(gè)文件可以在一個(gè) tar 歸檔中多次被保存。 每個(gè)歸檔成員都由一個(gè) TarInfo 對象來(lái)代表,詳情參見(jiàn) TarInfo 對象。

TarFile 對象可在 with 語(yǔ)句中作為上下文管理器使用。 當語(yǔ)句塊結束時(shí)它將自動(dòng)被關(guān)閉。 請注意在發(fā)生異常事件時(shí)被打開(kāi)用于寫(xiě)入的歸檔將不會(huì )被終結;只有內部使用的文件對象將被關(guān)閉。 相關(guān)用例請參見(jiàn) 例子。

3.2 新版功能: 添加了對上下文管理器協(xié)議的支持。

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)?

下列所有參數都是可選項并且也可作為實(shí)例屬性來(lái)訪(fǎng)問(wèn)。

name 是歸檔的路徑名稱(chēng)。 name 可以是一個(gè) path-like object。 如果給定了 fileobj 則它可以被省略。 在此情況下,如果對象的 name 屬性存在則它會(huì )被使用。

mode 可以為 'r' 表示從現有歸檔讀取,'a' 表示將數據追加到現有文件,'w' 表示創(chuàng )建新文件覆蓋現有文件,或者 'x' 表示僅在文件不存在時(shí)創(chuàng )建新文件。

如果給定了 fileobj,它會(huì )被用于讀取或寫(xiě)入數據。 如果可以被確定,則 mode 會(huì )被 fileobj 的模式所覆蓋。 fileobj 的使用將從位置 0 開(kāi)始。

備注

TarFile 被關(guān)閉時(shí),fileobj 不會(huì )被關(guān)閉。

format 控制用于寫(xiě)入的歸檔格式。 它必須為在模塊層級定義的常量 USTAR_FORMAT, GNU_FORMATPAX_FORMAT 中的一個(gè)。 當讀取時(shí),格式將被自動(dòng)檢測,即使單個(gè)歸檔中存在不同的格式。

tarinfo 參數可以被用來(lái)將默認的 TarInfo 類(lèi)替換為另一個(gè)。

如果 dereferenceFalse,則會(huì )將符號鏈接和硬鏈接添加到歸檔中。 如果為 True,則會(huì )將目標文件的內容添加到歸檔中。 在不支持符號鏈接的系統上參數將不起作用。

如果 ignore_zerosFalse,則會(huì )將空的數據塊當作歸檔的末尾來(lái)處理。 如果為 True,則會(huì )跳過(guò)空的(和無(wú)效的)數據塊并嘗試獲取盡可能多的成員。 此參數僅適用于讀取拼接的或損壞的歸檔。

debug 可設為從 0 (無(wú)調試消息) 到 3 (全部調試消息)。 消息會(huì )被寫(xiě)入到 sys.stderr。

如果 errorlevel0,則當使用 TarFile.extract() 時(shí)會(huì )忽略所有錯誤。 無(wú)論何種情況,當啟用調試時(shí)它們都將被顯示為調試輸出的錯誤消息。 如果為 1,則所有 fatal 錯誤會(huì )被作為 OSError 異常被引發(fā)。 如果為 2,則所有 non-fatal 錯誤也會(huì )被作為 TarError 異常被引發(fā)。

encodingerrors 參數定義了讀取或寫(xiě)入歸檔所使用的字符編碼格式以及要如何處理轉換錯誤。 默認設置將適用于大多數用戶(hù)。 要深入了解詳情可參閱 Unicode 問(wèn)題 小節。

可選的 pax_headers 參數是字符串的字典,如果 formatPAX_FORMAT 它將被作為 pax 全局標頭被添加。

在 3.2 版更改: 使用 'surrogateescape' 作為 errors 參數的默認值。

在 3.5 版更改: 添加了 'x' (單獨創(chuàng )建) 模式。

在 3.6 版更改: name 形參接受一個(gè) path-like object。

classmethod TarFile.open(...)?

作為替代的構造器。 tarfile.open() 函數實(shí)際上是這個(gè)類(lèi)方法的快捷方式。

TarFile.getmember(name)?

返回成員 nameTarInfo 對象。 如果 name 在歸檔中找不到,則會(huì )引發(fā) KeyError。

備注

如果一個(gè)成員在歸檔中出現超過(guò)一次,它的最后一次出現會(huì )被視為是最新的版本。

TarFile.getmembers()?

TarInfo 對象列表的形式返回歸檔的成員。 列表的順序與歸檔中成員的順序一致。

TarFile.getnames()?

以名稱(chēng)列表的形式返回成員。 它的順序與 getmembers() 所返回列表的順序一致。

TarFile.list(verbose=True, *, members=None)?

將內容清單打印到 sys.stdout。 如果 verboseFalse,則將只打印成員名稱(chēng)。 如果為 True,則輸出將類(lèi)似于 ls -l 的輸出效果。 如果給定了可選的 members,它必須為 getmembers() 所返回的列表的一個(gè)子集。

在 3.5 版更改: 添加了 members 形參。

TarFile.next()?

TarFile 被打開(kāi)用于讀取時(shí),以 TarInfo 對象的形式返回歸檔的下一個(gè)成員。 如果不再有可用對象則返回 None。

TarFile.extractall(path='.', members=None, *, numeric_owner=False)?

將歸檔中的所有成員提取到當前工作目錄或 path 目錄。 如果給定了可選的 members,則它必須為 getmembers() 所返回的列表的一個(gè)子集。 字典信息例如所有者、修改時(shí)間和權限會(huì )在所有成員提取完畢后被設置。 這樣做是為了避免兩個(gè)問(wèn)題:目錄的修改時(shí)間會(huì )在每當在其中創(chuàng )建文件時(shí)被重置。 并且如果目錄的權限不允許寫(xiě)入,提取文件到目錄的操作將失敗。

如果 numeric_ownerTrue,則將使用來(lái)自 tarfile 的 uid 和 gid 數值來(lái)設置被提取文件的所有者/用戶(hù)組。 在其他情況下,則會(huì )使用來(lái)自 tarfile 的名稱(chēng)值。

警告

絕不要未經(jīng)預先檢驗就從不可靠的源中提取歸檔文件。 這樣有可能在 path 之外創(chuàng )建文件,例如某些成員具有以 "/" 開(kāi)始的絕對路徑文件名或帶有兩個(gè)點(diǎn)號 ".." 的文件名。

在 3.5 版更改: 添加了 numeric_owner 形參。

在 3.6 版更改: path 形參接受一個(gè) path-like object。

TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False)?

從歸檔中提取出一個(gè)成員放入當前工作目錄,將使用其完整名稱(chēng)。 成員的文件信息會(huì )盡可能精確地被提取。 member 可以是一個(gè)文件名或 TarInfo 對象。 你可以使用 path 指定一個(gè)不同的目錄。 path 可以是一個(gè) path-like object。 將會(huì )設置文件屬性 (owner, mtime, mode) 除非 set_attrs 為假值。

如果 numeric_ownerTrue,則將使用來(lái)自 tarfile 的 uid 和 gid 數值來(lái)設置被提取文件的所有者/用戶(hù)組。 在其他情況下,則會(huì )使用來(lái)自 tarfile 的名稱(chēng)值。

備注

extract() 方法不會(huì )處理某些提取問(wèn)題。 在大多數情況下你應當考慮使用 extractall() 方法。

警告

查看 extractall() 的警告信息。

在 3.2 版更改: 添加了 set_attrs 形參。

在 3.5 版更改: 添加了 numeric_owner 形參。

在 3.6 版更改: path 形參接受一個(gè) path-like object。

TarFile.extractfile(member)?

將歸檔中的一個(gè)成員提取為文件對象。 member 可以是一個(gè)文件名或 TarInfo 對象。 如果 member 是一個(gè)常規文件或鏈接,則會(huì )返回一個(gè) io.BufferedReader 對象。 對于所有其他現有成員,則都將返回 None。 如果 member 未在歸檔中出現,則會(huì )引發(fā) KeyError。

在 3.3 版更改: 返回一個(gè) io.BufferedReader 對象。

TarFile.add(name, arcname=None, recursive=True, *, filter=None)?

將文件 name 添加到歸檔。 name 可以為任意類(lèi)型的文件(目錄、fifo、符號鏈接等等)。 如果給出 arcname 則它將為歸檔中的文件指定一個(gè)替代名稱(chēng)。 默認情況下會(huì )遞歸地添加目錄。 這可以通過(guò)將 recursive 設為 False 來(lái)避免。 遞歸操作會(huì )按排序順序添加條目。 如果給定了 filter,它應當為一個(gè)接受 TarInfo 對象并返回已修改 TarInfo 對象的函數。 如果它返回 NoneTarInfo 對象將從歸檔中被排除。 具體示例參見(jiàn) 例子。

在 3.2 版更改: 添加了 filter 形參。

在 3.7 版更改: 遞歸操作按排序順序添加條目。

TarFile.addfile(tarinfo, fileobj=None)?

TarInfo 對象 tarinfo 添加到歸檔。 如果給定了 fileobj,它應當是一個(gè) binary file,并會(huì )從中讀取 tarinfo.size 個(gè)字節添加到歸檔。 你可以直接創(chuàng )建 TarInfo 對象,或是使用 gettarinfo() 來(lái)創(chuàng )建。

TarFile.gettarinfo(name=None, arcname=None, fileobj=None)?

基于 os.stat() 的結果或者現有文件的相同數據創(chuàng )建一個(gè) TarInfo。 文件或者是命名為 name,或者是使用文件描述符指定為一個(gè) file object fileobj。 name 可以是一個(gè) path-like object。 如果給定了 arcname,則它將為歸檔中的文件指定一個(gè)替代名稱(chēng),在其他情況下,名稱(chēng)將從 fileobjname 屬性或 name 參數獲取。 名稱(chēng)應當是一個(gè)文本字符串。

你可以在使用 addfile() 添加 TarInfo 的某些屬性之前修改它們。 如果文件對象不是從文件開(kāi)頭進(jìn)行定位的普通文件對象,size 之類(lèi)的屬性就可能需要修改。 例如 GzipFile 之類(lèi)的文件就屬于這種情況。 name 也可以被修改,在這種情況下 arcname 可以是一個(gè)占位字符串。

在 3.6 版更改: name 形參接受一個(gè) path-like object。

TarFile.close()?

關(guān)閉 TarFile。 在寫(xiě)入模式下,會(huì )向歸檔添加兩個(gè)表示結束的零數據塊。

TarFile.pax_headers?

一個(gè)包含 pax 全局標頭的鍵值對的字典。

TarInfo 對象?

TarInfo 對象代表 TarFile 中的一個(gè)文件。 除了會(huì )存儲所有必要的文件屬性(例如文件類(lèi)型、大小、時(shí)間、權限、所有者等),它還提供了一些確定文件類(lèi)型的有用方法。 此對象 并不 包含文件數據本身。

TarInfo 對象可通過(guò) TarFile 的方法 getmember(), getmembers()gettarinfo() 返回。

class tarfile.TarInfo(name='')?

創(chuàng )建一個(gè) TarInfo 對象。

classmethod TarInfo.frombuf(buf, encoding, errors)?

基于字符串緩沖區 buf 創(chuàng )建并返回一個(gè) TarInfo 對象。

如果緩沖區無(wú)效則會(huì )引發(fā) HeaderError。

classmethod TarInfo.fromtarfile(tarfile)?

TarFile 對象 tarfile 讀取下一個(gè)成員并將其作為 TarInfo 對象返回。

TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')?

基于 TarInfo 對象創(chuàng )建一個(gè)字符串緩沖區。 有關(guān)參數的信息請參見(jiàn) TarFile 類(lèi)的構造器。

在 3.2 版更改: 使用 'surrogateescape' 作為 errors 參數的默認值。

TarInfo 對象具有以下公有數據屬性:

TarInfo.name?

歸檔成員的名稱(chēng)。

TarInfo.size?

以字節表示的大小。

TarInfo.mtime?

上次修改的時(shí)間。

TarInfo.mode?

權限位。

TarInfo.type?

文件類(lèi)型。 type 通常為以下常量之一: REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE。 要更方便地確定一個(gè) TarInfo 對象的類(lèi)型,請使用下述的 is*() 方法。

TarInfo.linkname?

目標文件名的名稱(chēng),該屬性?xún)H在類(lèi)型為 LNKTYPESYMTYPETarInfo 對象中存在。

TarInfo.uid?

最初保存該成員的用戶(hù)的用戶(hù) ID。

TarInfo.gid?

最初保存該成員的用戶(hù)的分組 ID。

TarInfo.uname?

用戶(hù)名。

TarInfo.gname?

分組名。

TarInfo.pax_headers?

一個(gè)包含所關(guān)聯(lián)的 pax 擴展標頭的鍵值對的字典。

TarInfo 對象還提供了一些便捷查詢(xún)方法:

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。

命令行接口?

3.4 新版功能.

tarfile 模塊提供了簡(jiǎn)單的命令行接口以便與 tar 歸檔進(jìn)行交互。

如果你想要創(chuàng )建一個(gè)新的 tar 歸檔,請在 -c 選項后指定其名稱(chēng)然后列出應當被包含的文件名:

$ python -m tarfile -c monty.tar  spam.txt eggs.txt

傳入一個(gè)字典也是可接受的:

$ python -m tarfile -c monty.tar life-of-brian_1979/

如果你想要將一個(gè) tar 歸檔提取到指定的目錄,請使用 -e 選項:

$ python -m tarfile -e monty.tar

你也可以通過(guò)傳入目錄名稱(chēng)將一個(gè) tar 歸檔提取到不同的目錄:

$ python -m tarfile -e monty.tar  other-dir/

要獲取一個(gè) tar 歸檔中文件的列表,請使用 -l 選項:

$ python -m tarfile -l monty.tar

命令行選項?

-l <tarfile>?
--list <tarfile>?

列出一個(gè) tarfile 中的文件名。

-c <tarfile> <source1> ... <sourceN>?
--create <tarfile> <source1> ... <sourceN>?

基于源文件創(chuàng )建 tarfile。

-e <tarfile> [<output_dir>]?
--extract <tarfile> [<output_dir>]?

如果未指定 output_dir 則會(huì )將 tarfile 提取到當前目錄。

-t <tarfile>?
--test <tarfile>?

檢測 tarfile 是否有效。

-v, --verbose?

更詳細地輸出結果。

例子?

如何將整個(gè) tar 歸檔提取到當前工作目錄:

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall()
tar.close()

如何通過(guò) TarFile.extractall() 使用生成器函數而非列表來(lái)提取一個(gè) 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()

如何基于一個(gè)文件名列表創(chuàng )建未壓縮的 tar 歸檔:

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
    tar.add(name)
tar.close()

使用 with 語(yǔ)句的同一個(gè)示例:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

如何讀取一個(gè) 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()

如何創(chuàng )建一個(gè)歸檔并使用 TarFile.add() 中的 filter 形參來(lái)重置用戶(hù)信息:

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 格式?

通過(guò) tarfile 模塊可以創(chuàng )建三種 tar 格式:

  • The POSIX.1-1988 ustar 格式 (USTAR_FORMAT)。 它支持最多 256 個(gè)字符的文件名長(cháng)度和最多 100 個(gè)字符的鏈接名長(cháng)度。 文件大小上限為 8 GiB。 這是一種老舊但廣受支持的格式。

  • GNU tar 格式 (GNU_FORMAT)。 它支持長(cháng)文件名和鏈接名、大于 8 GiB 的文件以及稀疏文件。 它是 GNU/Linux 系統上的事實(shí)標準。 tarfile 完全支持針對長(cháng)名稱(chēng)的 GNU tar 擴展,稀疏文件支持則限制為只讀。

  • POSIX.1-2001 pax 格式 (PAX_FORMAT)。 它是幾乎無(wú)限制的最靈活格式。 它支持長(cháng)文件名和鏈接名,大文件以及使用便捷方式存儲路徑名。 現代的 tar 實(shí)現,包括 GNU tar, bsdtar/libarchive 和 star,完全支持擴展 pax 特性;某些老舊或不維護的庫可能不受支持,但應當會(huì )將 pax 歸檔視為廣受支持的 ustar 格式。 這是目前新建歸檔的默認格式。

    它擴展了現有的 ustar 格式,包括用于無(wú)法以其他方式存儲的附加標頭。 存在兩種形式的 pax 標頭:擴展標頭只影響后續的文件標頭,全局標頭則適用于完整歸檔并會(huì )影響所有后續的文件。 為了便于移植,在 pax 標頭中的所有數據均以 UTF-8 編碼。

還有一些 tar 格式的其他變種,它們可以被讀取但不能被創(chuàng )建:

  • 古老的 V7 格式。 這是來(lái)自 Unix 第七版的第一個(gè) tar 格式,它只存儲常規文件和目錄。 名稱(chēng)長(cháng)度不能超過(guò) 100 個(gè)字符,并且沒(méi)有用戶(hù)/分組名信息。 某些歸檔在帶有非 ASCII 字符字段的情況下會(huì )產(chǎn)生計算錯誤的標頭校驗和。

  • SunOS tar 擴展格式。 此格式是 POSIX.1-2001 pax 格式的一個(gè)變種,但并不保持兼容。

Unicode 問(wèn)題?

最初 tar 格式被設計用來(lái)在磁帶機上生成備份,主要關(guān)注于保存文件系統信息。 現在 tar 歸檔通常用于文件分發(fā)和在網(wǎng)絡(luò )上交換歸檔。 最初格式(它是所有其他格式的基礎)的一個(gè)問(wèn)題是它沒(méi)有支持不同字符編碼格式的概念。 例如,一個(gè)在 UTF-8 系統上創(chuàng )建的普通 tar 歸檔如果包含非 ASCII 字符則將無(wú)法在 Latin-1 系統上被正確讀取。 文本元數據(例如文件名,鏈接名,用戶(hù)/分組名)將變?yōu)閾p壞狀態(tài)。 不幸的是,沒(méi)有什么辦法能夠自動(dòng)檢測一個(gè)歸檔的編碼格式。 pax 格式被設計用來(lái)解決這個(gè)問(wèn)題。 它使用通用字符編碼格式 UTF-8 來(lái)存儲非 ASCII 元數據。

tarfile 中字符轉換的細節由 TarFile 類(lèi)的 encodingerrors 關(guān)鍵字參數控制。

encoding 定義了用于歸檔中元數據的字符編碼格式。 默認值為 sys.getfilesystemencoding() 或是回退選項 'ascii'。 根據歸檔是被讀取還是被寫(xiě)入,元數據必須被解碼或編碼。 如果沒(méi)有正確設置 encoding,轉換可能會(huì )失敗。

errors 參數定義了不能被轉換的字符將如何處理。 可能的取值在 錯誤處理方案 小節列出。 默認方案為 'surrogateescape',它也被 Python 用于文件系統調用,參見(jiàn) 文件名,命令行參數,以及環(huán)境變量。。

對于 PAX_FORMAT 歸檔(默認格式),encoding 通常是不必要的,因為所有元數據都使用 UTF-8 來(lái)存儲。 encoding 僅在解碼二進(jìn)制 pax 標頭或存儲帶有替代字符的字符串等少數場(chǎng)景下會(huì )被使用。