"bz2" --- **bzip2** 圧縮のサポート
**********************************

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

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

このモジュールは、bzip2 アルゴリズムを用いて圧縮・展開を行う包括的なイ
ンターフェイスを提供します。

"bz2" モジュールには以下のクラスや関数があります:

* 圧縮ファイルを読み書きするための "open()" 関数と "BZ2File" クラス。

* インクリメンタルにデータを圧縮・展開するための "BZ2Compressor" およ
  び "BZ2Decompressor" クラス。

* 一度に圧縮・展開を行う "compress()" および "decompress()" 関数。


ファイルの圧縮/解凍
===================

bz2.open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None)

   bzip2 圧縮されたファイルを、バイナリモードかテキストモードでオープ
   ンし、*ファイルオブジェクト* を返します。

   "BZ2File" のコンストラクタと同様に、引数 *filename* には実際のファ
   イル名 ("str" または "bytes" オブジェクト) か、読み書きする既存のフ
   ァイルオブジェクトを指定します。

   引数 *mode* には、バイナリモード用に "'r'"、"'rb'"、"'w'"、"'wb'"、
   "'x'"、"'xb'"、"'a'"、あるいは "'ab'"、テキストモード用に "'rt'"、
   "'wt'"、"'xt'"、あるいは "'at'" を指定できます。デフォルトは "'rb'"
   です。

   引数 *compresslevel* には "BZ2File" コンストラクタと同様に 1 から 9
   の整数を指定します。

   バイナリモードでは、この関数は "BZ2File" コンストラクタ
   "BZ2File(filename, mode, compresslevel=compresslevel)" と等価です。
   この時、引数 *encoding*、*errors*、および *newline* を指定してはい
   けません。

   テキストモードでは、"BZ2File" オブジェクトが作成され、指定されたエ
   ンコーディング、エラーハンドラの挙動、および改行文字で
   "io.TextIOWrapper" にラップされます。

   バージョン 3.3 で追加.

   バージョン 3.4 で変更: "'x'" (排他的作成) モードが追加されました。

   バージョン 3.6 で変更: *path-like object* を受け入れるようになりま
   した。

class bz2.BZ2File(filename, mode='r', *, compresslevel=9)

   bzip2 圧縮ファイルをバイナリモードでオープンします。

   *filename* が "str" あるいは "bytes" オブジェクトの場合、それを名前
   とするファイルを直接開きます。そうでない場合、*filename* は圧縮デー
   タを読み書きする *ファイルオブジェクト* でなくてはなりません。

   引数 *mode* は読み込みモードの "'r'" (デフォルト)、上書きモードの
   "'w'"、排他的作成モードの "'x'"、あるいは追記モードの "'a'" のいず
   れかを指定できます。これらはそれぞれ "'rb'"、"'wb'"、"'xb'" および
   "'ab'" と等価です。

   *filename* が (実際のファイル名でなく) ファイルオブジェクトの場合、
   "'w'" はファイルを上書きせず、"'a'" と等価になります。

   *mode* が "'w'" あるいは "'a'" の場合、*compresslevel* に圧縮レベル
   を "1" から "9" の整数で指定できます。 圧縮率は "1" が最低で、"9" (
   デフォルト値) が最高です。

   *mode* の値が "'r'" の場合、入力ファイルは複数の圧縮ストリームでも
   構いません。

   "BZ2File" には、 "io.BufferedIOBase" で規定されているメソッドや属性
   のうち、 "detach()" と "truncate()" を除くすべてが備わっています。
   イテレーションと "with" 文をサポートしています。

   "BZ2File" は以下のメソッドも提供しています:

   peek([n])

      ファイル上の現在位置を変更せずにバッファのデータを返します。この
      メソッドは少なくとも 1 バイトのデータを返します (EOF の場合を除
      く)。返される正確なバイト数は規定されていません。

      注釈:

        "peek()" の呼び出しでは "BZ2File" のファイル位置は変わりません
        が、下層のファイルオブジェクトの位置が変わる惧れがあります
        (e.g. "BZ2File" を *filename* にファイルオブジェクトを渡して作
        成した場合)。

      バージョン 3.3 で追加.

   fileno()

      Return the file descriptor for the underlying file.

      バージョン 3.3 で追加.

   readable()

      Return whether the file was opened for reading.

      バージョン 3.3 で追加.

   seekable()

      Return whether the file supports seeking.

      バージョン 3.3 で追加.

   writable()

      Return whether the file was opened for writing.

      バージョン 3.3 で追加.

   read1(size=-1)

      Read up to *size* uncompressed bytes, while trying to avoid
      making multiple reads from the underlying stream. Reads up to a
      buffer's worth of data if size is negative.

      Returns "b''" if the file is at EOF.

      バージョン 3.3 で追加.

   readinto(b)

      Read bytes into *b*.

      Returns the number of bytes read (0 for EOF).

      バージョン 3.3 で追加.

   バージョン 3.1 で変更: "with" 構文のサポートが追加されました。

   バージョン 3.3 で変更: *filename* が実際のファイル名でなく *ファイ
   ルオブジェクト* だった場合のサポートが追加されました。"'a'" (追記)
   モードが追加され、複数のストリームの読み込みがサポートされました。

   バージョン 3.4 で変更: "'x'" (排他的作成) モードが追加されました。

   バージョン 3.5 で変更: "read()" メソッドが "None" を引数として受け
   取るようになりました。

   バージョン 3.6 で変更: *path-like object* を受け入れるようになりま
   した。

   バージョン 3.9 で変更: *buffering* パラメータは削除されました。
   Python 3.0 からは無視され非推奨となっています。開かれたファイルオブ
   ジェクトを渡し、ファイルの開きかたを制御します。*compresslevel* パ
   ラメータはキーワード専用になりました。

   バージョン 3.10 で変更: このクラスは、複数の同時読み出しや書き込み
   においては、既存の "gzip" や "lzma"  などの同等のクラスのように、ス
   レッド安全ではありません。


逐次圧縮および展開
==================

class bz2.BZ2Compressor(compresslevel=9)

   新しくコンプレッサオブジェクトを作成します。このオブジェクトはデー
   タの逐次的な圧縮に使用できます。一度に圧縮したい場合は、
   "compress()" 関数を使ってください。

   引数 *compresslevel* を指定する場合は、"1" から "9" までの整数を与
   えてください。 デフォルト値は "9" です。

   compress(data)

      データをコンプレッサオブジェクトに渡します。戻り値は圧縮されたデ
      ータですが、圧縮データを返すことができない場合は空のバイト文字列
      を返します。

      コンプレッサオブジェクトにデータをすべて渡し終えたら、"flush()"
      メソッドを呼び出し、圧縮プロセスを完了させてください。

   flush()

      圧縮プロセスを完了させ、内部バッファに残っている圧縮済みデータを
      返します。

      このメソッドを呼び出すと、それ以後コンプレッサオブジェクトは使用
      できなくなります。

class bz2.BZ2Decompressor

   新しくデコンプレッサオブジェクトを作成します。このオブジェクトは逐
   次的なデータ展開に使用できます。一度に展開したい場合は、
   "decompress()" 関数を使ってください。

   注釈:

     このクラスは、"decompress()" や "BZ2File" とは異なり、複数の圧縮
     レベルが混在しているデータを透過的に扱うことができません。
     "BZ2Decompressor" クラスを用いて、複数のストリームからなるデータ
     を展開する場合は、それぞれのストリームについてデコンプレッサオブ
     ジェクトを用意してください。

   decompress(data, max_length=-1)

      *data* (*bytes-like object*) を展開し、未圧縮のデータを bytes で
      返します。 *data* の一部は、後で "decompress()" の呼び出しに使用
      するため内部でバッファされている場合があります。 返されたデータ
      は、以前の "decompress()" の呼び出しの出力に連結する必要がありま
      す。

      *max_length* が非負の場合、最大 *max_length* バイトの展開データ
      を返します。この制限に達して、出力がさらに生成できる場合、
      "needs_input" が "False" に設定されます。この場合、
      "decompress()" を次に呼び出すと、*data* を "b''" として提供し、
      出力をさらに取得することができます。

      入力データの全てが圧縮され返された (*max_length* バイトより少な
      いためか *max_length* が負のため) 場合、 "needs_input" 属性は
      "True" になります。

      ストリームの終端に到達した後にデータを展開しようとすると
      "EOFError" が送出されます。 ストリームの終端の後ろの全てのデータ
      は無視され、その部分は "unused_data" 属性に保存されます。

      バージョン 3.5 で変更: "max_length" パラメータが追加されました。

   eof

      ストリーム終端記号に到達した場合 "True" を返します。

      バージョン 3.3 で追加.

   unused_data

      圧縮ストリームの末尾以降に存在したデータを表します。

      ストリームの末尾に達する前には、この属性には "b''" という値が収
      められています。

   needs_input

      "decompress()" メソッドが、新しい非圧縮入力を必要とせずにさらに
      展開データを提供できる場合、 "False" です。

      バージョン 3.5 で追加.


一括圧縮/解凍
=============

bz2.compress(data, compresslevel=9)

   *バイト類オブジェクト* の *data* を圧縮します。

   引数 *compresslevel* を指定する場合は、"1" から "9" までの整数を与
   えてください。 デフォルト値は "9" です。

   逐次的にデータを圧縮したい場合は、"BZ2Compressor" を使ってください
   。

bz2.decompress(data)

   *バイト類オブジェクト* の *data* を展開します。

   *data* が複数の圧縮ストリームから成る場合、そのすべてを展開します。

   逐次的に展開を行う場合は、"BZ2Decompressor" を使ってください。

   バージョン 3.3 で変更: 複数ストリームの入力をサポートしました。


使い方の例
==========

以下は、典型的な "bz2" モジュールの利用方法です。

"compress()" と "decompress()" を使い、圧縮して展開する実演をしていま
す:

>>> import bz2
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus
... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat.
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
>>> c = bz2.compress(data)
>>> len(data) / len(c)  # Data compression ratio
1.513595166163142
>>> d = bz2.decompress(c)
>>> data == d  # Check equality to original object after round-trip
True

"BZ2Compressor" を使い、逐次圧縮をしています:

>>> import bz2
>>> def gen_data(chunks=10, chunksize=1000):
...     """Yield incremental blocks of chunksize bytes."""
...     for _ in range(chunks):
...         yield b"z" * chunksize
...
>>> comp = bz2.BZ2Compressor()
>>> out = b""
>>> for chunk in gen_data():
...     # Provide data to the compressor object
...     out = out + comp.compress(chunk)
...
>>> # Finish the compression process.  Call this once you have
>>> # finished providing data to the compressor.
>>> out = out + comp.flush()

上の例は、非常に "ランダムでない" データストリーム (チャンク "b"z"" の
ストリーム) です。 ランダムなデータは圧縮率が低い傾向にある一方、揃っ
ていて、繰り返しのあるデータは通常は高い圧縮率を叩き出します。

bzip2 圧縮されたファイルをバイナリモードで読み書きしています:

>>> import bz2
>>> data = b"""\
... Donec rhoncus quis sapien sit amet molestie. Fusce scelerisque vel augue
... nec ullamcorper. Nam rutrum pretium placerat. Aliquam vel tristique lorem,
... sit amet cursus ante. In interdum laoreet mi, sit amet ultrices purus
... pulvinar a. Nam gravida euismod magna, non varius justo tincidunt feugiat.
... Aliquam pharetra lacus non risus vehicula rutrum. Maecenas aliquam leo
... felis. Pellentesque semper nunc sit amet nibh ullamcorper, ac elementum
... dolor luctus. Curabitur lacinia mi ornare consectetur vestibulum."""
>>> with bz2.open("myfile.bz2", "wb") as f:
...     # Write compressed data to file
...     unused = f.write(data)
...
>>> with bz2.open("myfile.bz2", "rb") as f:
...     # Decompress data from file
...     content = f.read()
...
>>> content == data  # Check equality to original object after round-trip
True
