"bz2" --- **bzip2** 압축 지원
*****************************

**소스 코드:** Lib/bz2.py

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

이 모듈은 bzip2 압축 알고리즘을 사용하여 데이터 압축과 압축 해제를 위
한 포괄적인 인터페이스를 제공합니다.

"bz2" 모듈에는 다음이 포함됩니다:

* 압축된 파일을 읽고 쓰기 위한 "open()" 함수와 "BZ2File" 클래스.

* 증분 압축(해제)을 위한 "BZ2Compressor"와 "BZ2Decompressor" 클래스.

* 일괄 압축(해제)을 위한 "compress()"와 "decompress()" 함수.

이 모듈의 모든 클래스는 다중 스레드에서 안전하게 액세스할 수 있습니다.


파일 압축(해제)
===============

bz2.open(filename, mode='r', 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에서 변경: *경로류 객체*를 받아들입니다.

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

   바이너리 모드로 bzip2 압축된 파일을 엽니다.

   *filename*이 "str"이나 "bytes" 객체면, 명명된 파일을 직접 엽니다.
   그렇지 않으면, *filename*은 *파일 객체* 여야 하며, 압축된 데이터를
   읽거나 쓰는 데 사용됩니다.

   *mode* 인자는 읽기를 위한 "'r'" (기본값), 덮어쓰기를 위한 "'w'", 배
   타적 생성을 위한 "'x'" 또는 덧붙이기를 위한 "'a'" 중 하나일 수 있습
   니다. 이들은 각각 "'rb'", "'wb'", "'xb'" 및 "'ab'"로 주어지는 것과
   동등합니다.

   *filename*이 (실제 파일 이름 대신) 파일 객체면, "'w'" 모드는 파일을
   자르지 않으며, 대신 "'a'"와 동등합니다.

   *buffering* 인자는 무시됩니다. 이것의 사용은 폐지되었습니다.

   *mode*가 "'w'"나 "'a'"이면, *compresslevel*은 압축 수준을 지정하는
   "1"과 "9" 사이의 정수일 수 있습니다: "1"은 압축률이 가장 낮고, "9"(
   기본값)는 압축률이 가장 높습니다.

   *mode*가 "'r'"이면, 입력 파일은 여러 개의 압축된 스트림을 이어 붙인
   것일 수 있습니다.

   "BZ2File"은 "detach()"와 "truncate()"를 제외하고,
   "io.BufferedIOBase"가 지정하는 모든 멤버를 제공합니다. 이터레이션과
   "with" 문이 지원됩니다.

   "BZ2File"는 다음 메서드도 제공합니다:

   peek([n])

      파일 위치를 전진시키지 않고 버퍼링 된 데이터를 반환합니다. (EOF
      에 있지 않은 한) 적어도 1바이트의 데이터가 반환됩니다. 반환되는
      정확한 바이트 수는 지정되지 않습니다.

      참고:

        "peek()"를 호출할 때 "BZ2File"의 파일 위치가 변경되지는 않지만
        , 하부 파일 객체의 위치는 변경될 수 있습니다 (예를 들어,
        "BZ2File"이 *filename*에 파일 객체를 전달하여 생성된 경우).

      버전 3.3에 추가.

   버전 3.1에서 변경: "with" 문에 대한 지원이 추가되었습니다.

   버전 3.3에서 변경: "fileno()", "readable()", "seekable()",
   "writable()", "read1()" 및 "readinto()" 메서드가 추가되었습니다.

   버전 3.3에서 변경: 실제 파일명 대신 *파일 객체* 인 *filename*에 대
   한 지원이 추가되었습니다.

   버전 3.3에서 변경: 다중 스트림 파일 읽기 지원과 함께, "'a'" (덧붙이
   기) 모드가 추가되었습니다.

   버전 3.4에서 변경: "'x'" (배타적 생성) 모드가 추가되었습니다.

   버전 3.5에서 변경: "read()" 메서드는 이제 "None" 인자를 받아들입니
   다.

   버전 3.6에서 변경: *경로류 객체*를 받아들입니다.


증분 압축(해제)
===============

class bz2.BZ2Compressor(compresslevel=9)

   새로운 압축기 객체를 만듭니다. 이 객체는 증분 적으로(incrementally)
   데이터를 압축하는 데 사용될 수 있습니다. 일괄(one-shot) 압축에는,
   대신 "compress()" 함수를 사용하십시오.

   주어진다면, *compresslevel*은 "1"과 "9" 사이의 정수여야 합니다. 기
   본값은 "9"입니다.

   compress(data)

      압축기 객체에 데이터를 제공합니다. 가능하면 압축된 데이터 청크를
      반환하고, 그렇지 않으면 빈 바이트열을 반환합니다.

      압축기에 데이터 제공이 끝나면, "flush()" 메서드를 호출하여 압축
      공정을 마무리하십시오.

   flush()

      압축 공정을 마칩니다. 내부 버퍼에 남아있는 압축된 데이터를 반환
      합니다.

      이 메서드가 호출된 후에는, 압축기 객체를 사용할 수 없습니다.

class bz2.BZ2Decompressor

   새로운 압축 해제기 객체를 만듭니다. 이 객체는 데이터를 증분 적으로
   압축 해제하는 데 사용될 수 있습니다. 일괄 압축에는, 대신
   "decompress()" 함수를 사용하십시오.

   참고:

     이 클래스는 "decompress()"와 "BZ2File"과 달리 다중 압축 스트림을
     포함하는 입력을 투명하게 처리하지 않습니다. "BZ2Decompressor"로
     다중 스트림 입력의 압축을 풀어야 한다면, 각 스트림 마다 새 압축
     해제기를 사용해야 합니다.

   decompress(data, max_length=-1)

      *data*(*바이트열류 객체*)의 압축을 풀고, 압축되지 않은 데이터를
      바이트열로 반환합니다. 일부 *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

      스트림의 끝(end-of-stream) 마커에 도달했으면 "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
