# `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` 인스턴스로 감싸집니다.

  Added in version 3.3.

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

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

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`은 `detach()`와 `truncate()`를 제외하고, `io.BufferedIOBase`가 지정하는 모든 멤버를 제공합니다. 이터레이션과 `with` 문이 지원됩니다.

  `BZ2File`는 다음 메서드와 어트리뷰트도 제공합니다:

  peek([n])

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

    참고

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

    Added in version 3.3.

  fileno()

    Return the file descriptor for the underlying file.

    Added in version 3.3.

  readable()

    Return whether the file was opened for reading.

    Added in version 3.3.

  seekable()

    Return whether the file supports seeking.

    Added in version 3.3.

  writable()

    Return whether the file was opened for writing.

    Added in version 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.

    Added in version 3.3.

  readinto(b)

    Read bytes into b.

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

    Added in version 3.3.

  mode

    `'rb'` for reading and `'wb'` for writing.

    Added in version 3.13.

  name

    The bzip2 file name. Equivalent to the `name` attribute of the underlying file object.

    Added in version 3.13.

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

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

  다중 스트림 파일 읽기 지원과 함께, `'a'` (덧붙이기) 모드가 추가되었습니다.

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

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

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

  버전 3.9에서 변경: buffering 매개 변수가 제거되었습니다. 파이썬 3.0부터 무시되고 폐지되었습니다. 파일을 여는 방법을 제어하려면 열린 파일 객체를 전달하십시오.

  compresslevel 매개 변수가 키워드 전용이 되었습니다.

  버전 3.10에서 변경: This class is thread unsafe in the face of multiple simultaneous readers or writers, just like its equivalent classes in `gzip` and `lzma` have always been.

## 증분 압축(해제)

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`.

    Added in version 3.3.

  unused_data

    압축된 스트림의 끝 이후에 발견된 데이터.

    스트림의 끝에 도달하기 전에 이 어트리뷰트를 액세스하면, 값은 `b''`가 됩니다.

  needs_input

    `decompress()` 메서드가 새로운 압축된 입력을 요구하기 전에 압축 해제된 데이터를 더 제공할 수 있으면 `False`.

    Added in version 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