tarfile --- 讀寫tar歸檔文件?

源代碼: Lib/tarfile.py


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

一些事實和數字:

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

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

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

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

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

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

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

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

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

模式

action

'r' or 'r:*'

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

'r:'

打開和讀取不使用壓縮。

'r:gz'

打開和讀取使用gzip 壓縮。

'r:bz2'

打開和讀取使用bzip2 壓縮。

'r:xz'

打開和讀取使用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:'

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

'w' or 'w:'

打開用于未壓縮的寫入。

'w:gz'

打開用于 gzip 壓縮的寫入。

'w:bz2'

打開用于 bzip2 壓縮的寫入。

'w:xz'

打開用于 lzma 壓縮的寫入。

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

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

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

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

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

模式

動作

'r|*'

打開 tar 塊的 以進行透明壓縮讀取。

'r|'

打開一個未壓縮的 tar 塊的 stream 用于讀取。

'r|gz'

打開一個 gzip 壓縮的 stream 用于讀取。

'r|bz2'

打開一個 bzip2 壓縮的 stream 用于讀取。

'r|xz'

打開一個 lzma 壓縮 stream 用于讀取。

'w|'

打開一個未壓縮的 stream 用于寫入。

'w|gz'

打開一個 gzip 壓縮的 stream 用于寫入。

'w|bz2'

打開一個 bzip2 壓縮的 stream 用于寫入。

'w|xz'

打開一個 lzma 壓縮的 stream 用于寫入。

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

在 3.6 版更改: name 形參接受一個 path-like object

class tarfile.TarFile

用于讀取和寫入 tar 歸檔的類。 請不要直接使用這個類:而要使用 tarfile.open()。 參見 TarFile 對象。

tarfile.is_tarfile(name)?

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

在 3.9 版更改: 支持文件或類文件對象。

tarfile 模塊定義了以下異常:

exception tarfile.TarError?

所有 tarfile 異常的基類。

exception tarfile.ReadError?

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

exception tarfile.CompressionError?

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

exception tarfile.StreamError?

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

exception tarfile.ExtractError?

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

exception tarfile.HeaderError?

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

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

tarfile.ENCODING?

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

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

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。

參見

模塊 zipfile

zipfile 標準模塊的文檔。

歸檔操作

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

GNU tar manual, Basic Tar Format

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

TarFile 對象?

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

TarFile 對象可在 with 語句中作為上下文管理器使用。 當語句塊結束時它將自動被關閉。 請注意在發(fā)生異常事件時被打開用于寫入的歸檔將不會被終結;只有內部使用的文件對象將被關閉。 相關用例請參見 例子

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

下列所有參數都是可選項并且也可作為實例屬性來訪問。

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

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

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

備注

TarFile 被關閉時,fileobj 不會被關閉。

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

tarinfo 參數可以被用來將默認的 TarInfo 類替換為另一個。

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

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

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

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

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

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

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

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

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

classmethod TarFile.open(...)?

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

TarFile.getmember(name)?

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

備注

如果一個成員在歸檔中出現超過一次,它的最后一次出現會被視為是最新的版本。

TarFile.getmembers()?

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

TarFile.getnames()?

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

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

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

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

TarFile.next()?

TarFile 被打開用于讀取時,以 TarInfo 對象的形式返回歸檔的下一個成員。 如果不再有可用對象則返回 None。

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

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

如果 numeric_ownerTrue,則將使用來自 tarfile 的 uid 和 gid 數值來設置被提取文件的所有者/用戶組。 在其他情況下,則會使用來自 tarfile 的名稱值。

警告

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

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

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

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

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

如果 numeric_ownerTrue,則將使用來自 tarfile 的 uid 和 gid 數值來設置被提取文件的所有者/用戶組。 在其他情況下,則會使用來自 tarfile 的名稱值。

備注

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

警告

查看 extractall() 的警告信息。

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

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

在 3.6 版更改: path 形參接受一個 path-like object

TarFile.extractfile(member)?

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

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

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

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

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

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

TarFile.addfile(tarinfo, fileobj=None)?

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

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

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

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

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

TarFile.close()?

關閉 TarFile。 在寫入模式下,會向歸檔添加兩個表示結束的零數據塊。

TarFile.pax_headers?

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

TarInfo 對象?

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

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

class tarfile.TarInfo(name='')?

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

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

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

如果緩沖區(qū)無效則會引發(fā) HeaderError。

classmethod TarInfo.fromtarfile(tarfile)?

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

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

基于 TarInfo 對象創(chuàng)建一個字符串緩沖區(qū)。 有關參數的信息請參見 TarFile 類的構造器。

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

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

TarInfo.name?

歸檔成員的名稱。

TarInfo.size?

以字節(jié)表示的大小。

TarInfo.mtime?

上次修改的時間。

TarInfo.mode?

權限位。

TarInfo.type?

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

TarInfo.linkname?

目標文件名的名稱,該屬性僅在類型為 LNKTYPESYMTYPETarInfo 對象中存在。

TarInfo.uid?

最初保存該成員的用戶的用戶 ID。

TarInfo.gid?

最初保存該成員的用戶的分組 ID。

TarInfo.uname?

用戶名。

TarInfo.gname?

分組名。

TarInfo.pax_headers?

一個包含所關聯的 pax 擴展標頭的鍵值對的字典。

TarInfo 對象還提供了一些便捷查詢方法:

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 模塊提供了簡單的命令行接口以便與 tar 歸檔進行交互。

如果你想要創(chuàng)建一個新的 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>?

基于源文件創(chuàng)建 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()

如何基于一個文件名列表創(chuàng)建未壓縮的 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()

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

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 模塊可以創(chuàng)建三種 tar 格式:

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

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

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

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

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

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

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

Unicode 問題?

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

tarfile 中字符轉換的細節(jié)由 TarFile 類的 encodingerrors 關鍵字參數控制。

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

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

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