12.5. "tarfile" --- tar アーカイブファイルの読み書き
****************************************************

バージョン 2.3 で追加.

**ソースコード:** Lib/tarfile.py

======================================================================

"tarfile" モジュールは、gzip、bz2  圧縮されたものを含む、tar アーカイ
ブを読み書きできます。".zip" ファイルの読み書きには "zipfile" モジュー
ルか、あるいは shutil の高レベル関数を使用してください。

いくつかの事実と形態:

* モジュールが利用可能な場合、"gzip"、"bz2" で圧縮されたアーカイブを
  読 み書きします。

* POSIX.1-1988 (ustar) フォーマットの読み書きをサポートしています。

* *longname*, *longlink* 拡張を含む GNU tar フォーマットの読み書きを
  サ ポートしています。 *sparse* 拡張は読み込みのみサポートしています
  。

* POSIX.1-2001 (pax) フォーマットの読み書きをサポートしています。

  バージョン 2.6 で追加.

* ディレクトリ、一般ファイル、ハードリンク、シンボリックリンク、fifo
  、 キャラクターデバイスおよびブロックデバイスを処理します。また、タ
  イム スタンプ、アクセス許可や所有者のようなファイル情報の取得および
  保存が 可能です。

注釈: Handling of multi-stream bzip2 files is not supported.
  Modules such as bz2file let you overcome this.

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

   パス名 *name* の "TarFile" オブジェクトを返します。"TarFile" オブジ
   ェクトと、利用出来るキーワード引数に関する詳細な情報については、
   TarFile オブジェクト 節を参照してください。

   *mode* は "'filemode[:compression]'" の形式をとる文字列でなければな
   りません。デフォルトの値は "'r'" です。以下に *mode* のとりうる組み
   合わせすべてを示します:

   +--------------------+-----------------------------------------------+
   | mode               | action                                        |
   +====================+===============================================+
   | "'r' または 'r:*'" | 圧縮方法に関して透過的に、読み込み用にオープ  |
   |                    | ンします (推奨)。                             |
   +--------------------+-----------------------------------------------+
   | "'r:'"             | 非圧縮で読み込み用に排他的にオープンします。  |
   +--------------------+-----------------------------------------------+
   | "'r:gz'"           | gzip 圧縮で読み込み用にオープンします。       |
   +--------------------+-----------------------------------------------+
   | "'r:bz2'"          | bzip2 圧縮で読み込み用にオープンします。      |
   +--------------------+-----------------------------------------------+
   | "'a' または 'a:'"  | 非圧縮で追記用にオープンします。ファイルが存  |
   |                    | 在しない場合は新たに作 成されます。           |
   +--------------------+-----------------------------------------------+
   | "'w' または 'w:'"  | 非圧縮で書き込み用にオープンします。          |
   +--------------------+-----------------------------------------------+
   | "'w:gz'"           | gzip 圧縮で書き込み用にオープンします。       |
   +--------------------+-----------------------------------------------+
   | "'w:bz2'"          | bzip2 圧縮で書き込み用にオープンします。      |
   +--------------------+-----------------------------------------------+

   "'a:gz'"、"'a:bz2'" は利用できないことに注意して下さい。もし *mode*
   が、ある (圧縮した) ファイルを読み込み用にオープンするのに適してい
   ないなら、"ReadError" が送出されます。これを防ぐには *mode* "'r'"
   を使って下さい。もし圧縮方式がサポートされていなければ、
   "CompressionError" が送出されます。

   もし *fileobj* が指定されていれば、それは *name* でオープンされた *
   ファイルオブジェクト* の代替として使うことができます。そのファイル
   オブジェクトの位置が 0 であることを前提に動作します。

   "'w:gz'"、"'r:gz'"、"'w:bz2'"、"'r:bz2'" モードの場合、
   "tarfile.open()" はファイルの圧縮レベルを指定するキーワード引数
   *compresslevel* (デフォルトは "9") を受け付けます。

   特別な目的のために、*mode* には 2 番目の形式: "'ファイルモード|[圧
   縮方式]'" があります。この形式を使うと、"tarfile.open()" が返すのは
   、データをブロックからなるストリームとして扱う "TarFile" オブジェク
   トになります。この場合、ファイルに対してランダムなシークが行えなく
   なります。*fileobj* を指定する場合、 "read()" および "write()" メソ
   ッドを持つ (*mode* に依存した) 任意のオブジェクトにできます。
   *bufsize* にはブロックサイズを指定します。デフォルトは "20 * 512"
   バイトです。"sys.stdin"、ソケットファイルオブジェクト、あるいはテー
   プデバイスと組み合わせる場合にはこの形式を使ってください。ただし、
   このような "TarFile" オブジェクトにはランダムアクセスを行えないとい
   う制限があります。例 節を参照してください。現在可能なモードは以下の
   とおりです。

   +---------------+----------------------------------------------+
   | モード        | 動作                                         |
   +===============+==============================================+
   | "'r|*'"       | tar ブロックの *stream* を圧縮方法に関して透 |
   |               | 過的に読み込み用にオー プンします。          |
   +---------------+----------------------------------------------+
   | "'r|'"        | 非圧縮 tar ブロックの *stream* を読み込み用  |
   |               | にオープンします。                           |
   +---------------+----------------------------------------------+
   | "'r|gz'"      | gzip 圧縮の *stream* を読み込み用にオープン  |
   |               | します。                                     |
   +---------------+----------------------------------------------+
   | "'r|bz2'"     | bzip2 圧縮の *stream* を読み込み用にオープン |
   |               | します。                                     |
   +---------------+----------------------------------------------+
   | "'w|'"        | 非圧縮の *stream* を書き込み用にオープンしま |
   |               | す。                                         |
   +---------------+----------------------------------------------+
   | "'w|gz'"      | gzip 圧縮の *stream* を書き込み用にオープン  |
   |               | します。                                     |
   +---------------+----------------------------------------------+
   | "'w|bz2'"     | bzip2 圧縮の *stream* を書き込み用にオープン |
   |               | します。                                     |
   +---------------+----------------------------------------------+

class tarfile.TarFile

   tar アーカイブを読み書きするためのクラスです。このクラスを直接使わ
   ず、代わりに "tarfile.open()" を使ってください。TarFile オブジェク
   ト を参照してください。

tarfile.is_tarfile(name)

   もし *name* が tar アーカイブファイルであり、"tarfile" モジュールで
   読み込める場合に "True" を返します。

class tarfile.TarFileCompat(filename, mode='r', compression=TAR_PLAIN)

   "zipfile" 風なインターフェースを持つ tar アーカイブへの制限されたア
   クセスのためのクラスです。詳細は "zipfile" のドキュメントを参照して
   ください。 *compression* は、以下の定数のどれかでなければなりません
   :

   TAR_PLAIN

      非圧縮 tar アーカイブのための定数。

   TAR_GZIPPED

      "gzip" 圧縮 tar アーカイブのための定数。

   バージョン 2.6 で非推奨: "TarFileCompat" クラスは Python 3 で削除さ
   れました。

exception tarfile.TarError

   すべての "tarfile" 例外のための基本クラスです。

exception tarfile.ReadError

   tar アーカイブがオープンされた時、"tarfile" モジュールで操作できな
   いか、あるいは何か無効であるとき送出されます。

exception tarfile.CompressionError

   圧縮方法がサポートされていないか、あるいはデータを正しくデコードで
   きない時に送出されます。

exception tarfile.StreamError

   ストリームのような "TarFile" オブジェクトで典型的な制限のために送出
   されます。

exception tarfile.ExtractError

   "TarFile.extract()" を使った時に *致命的でない* エラーに対して送出
   されます。ただし "TarFile.errorlevel""== 2" の場合に限ります。

モジュールレベルで以下の定数が利用出来ます。

tarfile.ENCODING

   既定の文字エンコーディング。Windows では "'utf-8'" 、それ以外では
   "sys.getfilesystemencoding()" の返り値です。

exception tarfile.HeaderError

   "TarInfo.frombuf()" メソッドが取得したバッファーが不正だったときに
   送出されます。

   バージョン 2.6 で追加.

以下の各定数は、"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 manual, Basic Tar Format
     GNU tar 拡張機能を含む、tar アーカイブファイルのためのドキュメン
     ト。


12.5.1. TarFile オブジェクト
============================

"TarFile" オブジェクトは、tar アーカイブへのインターフェースを提供しま
す。tar アーカイブは一連のブロックです。アーカイブメンバー (保存された
ファイル) は、ヘッダーブロックとそれに続くデータブロックで構成されてい
ます。一つの tar アーカイブにファイルを何回も保存することができます。
各アーカイブメンバーは、"TarInfo" オブジェクトで確認できます。詳細につ
いては TarInfo オブジェクト を参照してください。

"TarFile" オブジェクトは "with" 文のコンテキストマネージャーとして利用
できます。with ブロックが終了したときにオブジェクトはクローズされます
。例外が発生した時、内部で利用されているファイルオブジェクトのみがクロ
ーズされ、書き込み用にオープンされたアーカイブのファイナライズは行われ
ないことに注意してください。例 節のユースケースを参照してください。

バージョン 2.7 で追加: コンテキスト管理のプロトコルがサポートされまし
た。

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors=None, pax_headers=None, debug=0, errorlevel=0)

   以下のすべての引数はオプションで、インスタンス属性としてもアクセス
   できます。

   *name* はアーカイブのパス名です。*fileobj* が渡された場合は省略可能
   です。その場合、ファイルオブジェクトに "name" 属性があれば、それを
   利用します。

   *mode* は、既存のアーカイブから読み込むための "'r'"、既存のアーカイ
   ブに追記するための "'a'"、あるいは既存のファイルがあれば上書きして
   新しいファイルを作成する "'w'" のいずれかです。

   *fileobj* が与えられていれば、それを使ってデータを読み書きします。
   もしそれが決定できれば、*mode* は *fileobj* のモードで上書きされま
   す。*fileobj* は位置 0 から利用されます。

   注釈: "TarFile" をクローズした時、*fileobj* はクローズされません
     。

   *format* はアーカイブのフォーマットを制御します。モジュールレベルで
   定義されている、"USTAR_FORMAT"、"GNU_FORMAT"、あるいは "PAX_FORMAT"
   のいずれかである必要があります。

   バージョン 2.6 で追加.

   *tarinfo* 引数を利用して、デフォルトの "TarInfo" クラスを別のクラス
   で置き換えることができます。

   バージョン 2.6 で追加.

   *dereference* が "False" だった場合、シンボリックリンクやハードリン
   クがアーカイブに追加されます。"True" だった場合、リンクのターゲット
   となるファイルの内容がアーカイブに追加されます。シンボリックリンク
   をサポートしていないシステムでは効果がありません。

   *ignore_zeros* が "False" だった場合、空ブロックをアーカイブの終端
   として扱います。"True" だった場合、空の (無効な) ブロックをスキップ
   して、可能な限り多くのメンバーを取得しようとします。このオプション
   は、連結されたり、壊れたアーカイブファイルを扱うときにのみ、意味が
   あります。

   *debug* は "0" (デバッグメッセージ無し) から "3" (全デバッグメッセ
   ージ) まで設定できます。このメッセージは "sys.stderr" に書き込まれ
   ます。

   *errorlevel* が "0" の場合、"TarFile.extract()" 使用時にすべてのエ
   ラーが無視されます。エラーが無視された場合でも、*debug* が有効であ
   れば、エラーメッセージは出力されます。 *errorlevel* が``1`` の場合
   、すべての *致命的な(fatal)* エラーは "OSError" または "IOError" を
   送出します。"2" の場合、すべての *致命的でない(non-fatal)* エラーも
   "TarError" 例外として送出されます。

   *encoding* と *errors* 引数は、文字列と unicode オブジェクトとの間
   の相互変換方法を指定します。デフォルトの設定で、ほとんどのユーザー
   でうまく動作するでしょう。詳しい情報は、 Unicode に関する問題 節を
   参照してください。

   バージョン 2.6 で追加.

   *pax_headers* 引数は、オプションの、 unicode 文字列の辞書で、
   *format* が "PAX_FORMAT" だった場合に pax グローバルヘッダに追加さ
   れます。

   バージョン 2.6 で追加.

classmethod TarFile.open(...)

   代替コンストラクターです。モジュールレベルでの "tarfile.open()" 関
   数は、実際はこのクラスメソッドへのショートカットです。

TarFile.getmember(name)

   メンバー *name* に対する "TarInfo" オブジェクトを返します。*name*
   がアーカイブに見つからなければ、"KeyError" が送出されます。

   注釈: アーカイブ内にメンバーが複数ある場合は、最後に出現するもの
     が最新 のバージョンとみなされます。

TarFile.getmembers()

   "TarInfo" アーカイブのメンバーをオブジェクトのリストとして返します
   。このリストはアーカイブ内のメンバーと同じ順番です。

TarFile.getnames()

   メンバーをその名前のリストを返します。これは "getmembers()" で返さ
   れるリストと同じ順番です。

TarFile.list(verbose=True)

   内容の一覧を "sys.stdout" に出力します。*verbose* が "False" であれ
   ば、メンバー名のみ表示します。"True" であれば、 **ls -l** に似た出
   力を生成します。

TarFile.next()

   "TarFile" が読み込み用にオープンされている時、アーカイブの次のメン
   バーを "TarInfo" オブジェクトとして返します。もしそれ以上利用可能な
   ものがなければ、"None" を返します。

TarFile.extractall(path=".", members=None)

   すべてのメンバーをアーカイブから現在の作業ディレクトリまたは *path*
   に抽出します。オプションの *members* が与えられるときには、
   "getmembers()" で返されるリストの一部でなければなりません。所有者、
   変更時刻、アクセス権限のようなディレクトリ情報はすべてのメンバーが
   抽出された後にセットされます。これは二つの問題を回避するためです。
   一つはディレクトリの変更時刻はその中にファイルが作成されるたびにリ
   セットされるということ、もう一つはディレクトリに書き込み許可がなけ
   ればその中のファイル抽出は失敗してしまうということです。

   警告: 内容を信頼できない tar アーカイブを、事前の内部チェック前に
     展開し てはいけません。ファイルが *path* の外側に作られる可能性が
     ありま す。例えば、""/"" で始まる絶対パスのファイル名や、2 重ドッ
     ト "".."" で始まるパスのファイル名です。

   バージョン 2.5 で追加.

TarFile.extract(member, path="")

   アーカイブからメンバーの完全な名前を使って、現在のディレクトリに展
   開します。ファイル情報はできる限り正確に展開されます。 *member* は
   ファイル名もしくは "TarInfo" オブジェクトです。 *path* を使って別の
   ディレクトリを指定することもできます。

   注釈: "extract()" メソッドはいくつかの展開に関する問題を扱いませ
     ん。ほ とんどの場合、"extractall()" メソッドの利用を考慮するべき
     です。

   警告: "extractall()" の警告を参してください。

TarFile.extractfile(member)

   アーカイブからメンバーをファイルオブジェクトとして抽出します。
   *member* は、ファイル名あるいは "TarInfo" オブジェクトです。もし
   *member* が普通のファイルであれば、ファイル風のオブジェクトを返しま
   す。もし *member* がリンクであれば、ファイル風のオブジェクトをリン
   クのターゲットから構成します。もし *member* が上のどれでもなければ
   、 "None" が返されます。

   注釈: ファイル風のオブジェクトは読み出し専用です。このオブジェク
     トは "read()", "readline()", "readlines()", "seek()", "tell()",
     "close()". の各メソッドを提供し、行に対するイテレーションをサポー
     トします。

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

   ファイル *name* をアーカイブに追加します。 *name* は、任意のファイ
   ルタイプ (ディレクトリ、fifo、シンボリックリンク等)です。もし
   *arcname* が与えられていれば、それはアーカイブ内のファイルの代替名
   を指定します。デフォルトではディレクトリは再帰的に追加されます。こ
   れは、 *recursive* を "False" に設定することで避けることができます
   。 *exclude* を指定する場合、それは1つのファイル名を引数にとってブ
   ール値を返す関数である必要があります。この関数の戻り値が "True" の
   場合、そのファイルが除外されます。 "False" の場合、そのファイルは追
   加されます。 *filter* を指定する場合、それは "TarInfo" オブジェクト
   を引数として受け取り、操作した "TarInfo" オブジェクトを返す関数でな
   ければなりません。代わりに "None" を返した場合、 "TarInfo" オブジェ
   クトはアーカイブから除外されます。 例 にある例を参照してください。

   バージョン 2.6 で変更: *exclude* パラメータが追加されました。

   バージョン 2.7 で変更: *filter* パラメータが追加されました。

   バージョン 2.7 で非推奨: *exclude* 引数は廃止予定です。代わりに
   *filter* 引数を利用してください。将来 *exclude* 引数が削除されたと
   きに互換性を保つため、 *filter* は位置引数ではなくてキーワード引数
   として利用するべきです。

TarFile.addfile(tarinfo, fileobj=None)

   "TarInfo" オブジェクト *tarinfo* をアーカイブに追加します。
   *fileobj* が与えられている場合は、"tarinfo.size" バイトがそれから読
   まれ、アーカイブに追加されます。 "TarInfo" オブジェクトは直接もしく
   は "gettarinfo()" を使って作成することができます。

   注釈: Windows プラットフォームでは、*fileobj* は、ファイルサイズ
     に関す る問題を避けるために、常にモード "'rb'" でオープンするべき
     です。

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

   "os.stat()" の結果か、既存のファイルに相当するものから、"TarInfo"
   オブジェクトを作成します。このファイルは、*name* で名付けられるか、
   ファイル記述子を持つ *file object* *fileobj* として指定されます。
   *arcname* が与えられた場合、アーカイブ内のファイルに対して代替名を
   指定します。与えられない場合、名前は *fileobj* の "name" 属性、もし
   くは *name* 引数から取られます。

   "TarInfo" の属性の一部は、"addfile()" を使用して追加する前に修正で
   きます。ファイルオブジェクトが、ファイルの先頭にある通常のファイル
   オブジェクトでない場合、 "size" などの属性は修正が必要かもしれませ
   ん。これは、 "GzipFile" などの属性に当てはまります。"name" も修正で
   きるかもしれず、この場合、*arcname* はダミーの文字列にすることがで
   きます。

TarFile.close()

   "TarFile" をクローズします。書き込みモードでは、完了ゼロブロックが
   2 個アーカイブに追加されます。

TarFile.posix

   この値を "True" にすることは、 "format" を "USTAR_FORMAT" にするこ
   とと同じです。この値を "False" にすることは、 "format" を
   "GNU_FORMAT" にすることと同じです。

   バージョン 2.4 で変更: *posix* のデフォルト値が "False" になりまし
   た。

   バージョン 2.6 で非推奨: 代わりに "format" 属性を利用してください。

TarFile.pax_headers

   pax グローバルヘッダーに含まれる key-value ペアの辞書です。

   バージョン 2.6 で追加.


12.5.2. TarInfo オブジェクト
============================

"TarInfo" オブジェクトは "TarFile" の一つのメンバーを表します。ファイ
ルに必要なすべての属性 (ファイルタイプ、ファイルサイズ、時刻、アクセス
権限、所有者等のような) を保存する他に、そのタイプを決定するのに役に立
ついくつかのメソッドを提供します。これにはファイルのデータそのものは *
含まれません* 。

"TarInfo" オブジェクトは "TarFile" のメソッド "getmember()"、
"getmembers()" および "gettarinfo()" によって返されます。

class tarfile.TarInfo(name="")

   "TarInfo" オブジェクトを作成します。

TarInfo.frombuf(buf)

   "TarInfo" オブジェクトを文字列バッファー *buf* から作成して返します
   。

   バージョン 2.6 で追加: バッファーが不正な場合 "HeaderError" を送出
   します。

TarInfo.fromtarfile(tarfile)

   "TarFile" オブジェクトの *tarfile* から、次のメンバーを読み込んで、
   それを "TarInfo" オブジェクトとして返します。

   バージョン 2.6 で追加.

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

   "TarInfo" オブジェクトから文字列バッファーを作成します。引数につい
   ての情報は、"TarFile" クラスのコンストラクターを参照してください。

   バージョン 2.6 で変更: 引数が追加されました。

"TarInfo" オブジェクトには以下のデータ属性があります:

TarInfo.name

   アーカイブメンバーの名前。

TarInfo.size

   バイト単位でのサイズ。

TarInfo.mtime

   最後に変更された時刻。

TarInfo.mode

   許可ビット。

TarInfo.type

   ファイルタイプ。*type* は通常、定数 "REGTYPE"、"AREGTYPE"、
   "LNKTYPE"、"SYMTYPE"、"DIRTYPE"、"FIFOTYPE"、"CONTTYPE"、"CHRTYPE"
   、"BLKTYPE"、あるいは "GNUTYPE_SPARSE" のいずれかです。"TarInfo" オ
   ブジェクトのタイプをもっと簡単に解決するには、下記の "is*()" メソッ
   ドを使って下さい。

TarInfo.linkname

   リンク先ファイルの名前。これはタイプ "LNKTYPE" と "SYMTYPE" の
   "TarInfo" オブジェクトにだけ存在します。

TarInfo.uid

   ファイルメンバーを保存した元のユーザーのユーザー ID。

TarInfo.gid

   ファイルメンバーを保存した元のユーザーのグループ ID。

TarInfo.uname

   ファイルメンバーを保存した元のユーザーのユーザー名。

TarInfo.gname

   ファイルメンバーを保存した元のユーザーのグループ名。

TarInfo.pax_headers

   pax 拡張ヘッダーに関連付けられた、key-value ペアの辞書。

   バージョン 2.6 で追加.

"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" を返します。


12.5.3. 例
==========

tar アーカイブから現在のディレクトリにすべて抽出する方法:

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

tar アーカイブの一部を、リストの代わりにジェネレーター関数を利用して
"TarFile.extractall()" で展開する方法:

   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",
       if tarinfo.isreg():
           print "a regular file."
       elif tarinfo.isdir():
           print "a directory."
       else:
           print "something else."
   tar.close()

"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()


12.5.4. サポートしている tar フォーマット
=========================================

"tarfile" モジュールは 3 種類の tar フォーマットを作成することができま
す:

* POSIX.1-1988 ustar format ("USTAR_FORMAT"). ファイル名の長さは256
  文 字までで、リンク名の長さは100文字までです。最大のファイルサイズは
  8GiBです。このフォーマットは古くて制限が多いですが、広くサポートされ
  ています。

* GNU tar format ("GNU_FORMAT"). 長いファイル名とリンク名、8GiBを超
  え るファイルやスパース(sparse)ファイルをサポートしています。これは
  GNU/Linux システムにおいてデファクト・スタンダードになっています。
  "tarfile" モジュールは長いファイル名を完全にサポートしています。 ス
  パースファイルは読み込みのみサポートしています。

* POSIX.1-2001 pax フォーマット ("PAX_FORMAT")。最も柔軟性があり、ほ
  ぼ 制限が無いフォーマットです。長いファイル名やリンク名、大きいファ
  イル をサポートし、パス名をポータブルな方法で保存します。しかし、現
  在のと ころ、すべての tar の実装が pax フォーマットを正しく扱えるわ
  けではあ りません。

  *pax* フォーマットは既存の *ustar* フォーマットの拡張です。*ustar*
  では保存できない情報を追加のヘッダーを利用して保存します。*pax* には
  2 種類のヘッダーがあります。1 つ目は拡張ヘッダーで、その次のファイル
  ヘッダーに影響します。2 つ目はグローバルヘッダーで、アーカイブ全体に
  対して有効で、それ以降のすべてのファイルに影響します。すべての pax
  ヘッダーの内容は、ポータブル性のために *UTF-8* で保存されます。

他にも、読み込みのみサポートしている tar フォーマットがいくつかありま
す:

* ancient V7 フォーマット。これは Unix 7th Edition から存在する、最
  初 の tar フォーマットです。通常のファイルとディレクトリのみ保存しま
  す 。名前は 100 文字を超えてはならず、ユーザー/グループ名に関する情
  報は 保存されません。いくつかのアーカイブは、フィールドが ASCII でな
  い文 字を含む場合に、ヘッダーのチェックサムの計算を誤ります。

* SunOS tar 拡張フォーマット。POSIX.1-2001 pax フォーマットの亜流で
  す が、互換性がありません。


12.5.5. Unicode に関する問題
============================

tarフォーマットはもともと、テープドライブにファイルシステムのバックア
ップを取る目的で設計されました。現在、tarアーカイブはファイルを配布す
る場合に一般的に用いられ、ネットワークごしに送受信されます。オリジナル
のフォーマットの抱える1つの問題(ほか多くのフォーマットも同じですが)は
、文字エンコーディングが異なる環境を考慮していないことです。例えば、通
常の *UTF-8* の環境で作成されたアーカイブは、非ASCII文字を含んでいた場
合 *Latin-1* のシステムでは正しく読み込むことができません。非ASCII文字
を含む名前(ファイル名、リンク名、ユーザー/グループ名)が破壊されます。
不幸なことに、アーカイブのエンコーディングを自動検出する方法はありませ
ん。

pax フォーマットはこの問題を解決するように設計されました。このフォーマ
ットは、非ASCII文字の名前を *UTF-8* で保存します。 pax アーカイブを読
み込むときに、この *UTF-8* の名前がローカルのファイルシステムのエンコ
ーディングに変換されます。

unicode 変換の動作は、 "TarFile" クラスの *encoding* と *errors* キー
ワード引数によって制御されます。

*encoding* のデフォルト値はローカルの文字エンコーディングです。これは
"sys.getfilesystemencoding()" と "sys.getdefaultencoding()" から取得さ
れます。読み込みモードでは、 *encoding* は pax フォーマット内の
unicode の名前をローカルの文字エンコーディングに変換するために利用され
ます。書き込みモードでは、 *encoding* の扱いは選択されたアーカイブフォ
ーマットに依存します。 "PAX_FORMAT" の場合、入力された非ASCII文字を含
む文字は *UTF-8* 文字列として保存する前に一旦デコードする必要があるの
で、そこで *encoding* が利用されます。それ以外のフォーマットでは、
*encoding* は、入力された名前に unicode が含まれない限りは利用されませ
ん。unicodeが含まれている場合、アーカイブに保存する前に *encoding* で
エンコードされます。

*errors* 引数は、 *encoding* を利用して変換できない文字の扱いを指定し
ます。利用可能な値は、 Codec 基底クラス 節でリストアップされています。
読み込みモードでは、追加の値として "'utf-8'" を選択することができ、エ
ラーが発生したときは *UTF-8* を利用することができます。(これがデフォル
トです) 書き込みモードでは、 *errors* のデフォルト値は "'strict'" にな
っていて、名前が気づかないうちに変化することが無いようにしています。
