bz2 — bzip2 압축 지원

bz2 — bzip2 압축 지원

(소스: Lib/bz2.py)

이 모듈은 bzip2 압축 알고리즘으로 데이터를 압축·해제하는 포괄적인 인터페이스를 제공해요. bz2 모듈은 다음을 포함해요.

  • 압축 파일을 읽고 쓰는 open() 함수와 BZ2File 클래스
  • 증분 (해)압축을 위한 BZ2CompressorBZ2Decompressor 클래스
  • 원샷 (해)압축을 위한 compress()decompress() 함수

이것은 선택적 모듈이에요. CPython 사본에서 없다면 배포자(파이썬을 제공한 사람)의 문서를 찾아보세요.

출처: Python documentation

본문

파일 (해)압축

  • bz2.open(filename, mode='rb', compresslevel=9, encoding=None, errors=None, newline=None): bzip2 압축 파일을 바이너리 또는 텍스트 모드로 열고 파일 객체를 반환. filename은 실제 파일 이름(str/bytes) 또는 기존 파일 객체일 수 있어요. mode는 바이너리 모드 'r','rb','w','wb','x','xb','a','ab' 또는 텍스트 모드 'rt','wt','xt','at', 기본 'rb'. compresslevel은 1~9 정수. 바이너리 모드에선 BZ2File(filename, mode, compresslevel=compresslevel)과 동등하고 encoding/errors/newline을 주면 안 돼요. 텍스트 모드에선 BZ2File 객체를 만들어 지정된 인코딩·오류 처리·줄바꿈으로 io.TextIOWrapper에 감싸요. (3.3 추가, 3.4에서 'x' 모드, 3.6에서 path-like 객체 수용)

  • class bz2.BZ2File(filename, mode='r', *, compresslevel=9): bzip2 압축 파일을 바이너리 모드로 열어요. filename이 str/bytes면 명명된 파일을 직접 열고, 아니면 파일 객체여야 해요. mode는 'r'(읽기, 기본), 'w'(덮어쓰기), 'x'(배타적 생성), 'a'(추가). 파일 객체를 넘기면 'w'는 파일을 잘라내지 않고 'a'와 동등해져요. 'w'/'a'에서 compresslevel은 1~9(1이 가장 덜, 9 기본이 가장 많이). 'r'에선 입력 파일이 여러 압축 스트림의 연결일 수 있어요. BZ2Fileio.BufferedIOBase의 멤버를 detach()truncate()를 제외하고 모두 제공해요. 반복과 with 문을 지원해요.

    BZ2File의 메서드·속성:

    • peek([n]): 파일 위치를 진행하지 않고 버퍼된 데이터 반환. 최소 1바이트(EOF가 아니면) 반환. 정확한 바이트 수는 명시되지 않아요. peek()을 호출해도 BZ2File 위치는 안 바뀌지만 기반 파일 객체의 위치는 바뀔 수 있어요. (3.3 추가)
    • fileno(): 기반 파일의 파일 디스크립터 반환. (3.3)
    • readable(): 읽기용으로 열렸는지. (3.3)
    • seekable(): 탐색을 지원하는지. (3.3)
    • writable(): 쓰기용으로 열렸는지. (3.3)
    • read1(size=-1): 기반 스트림에서 여러 번 읽기를 피하면서 size까지 압축되지 않은 바이트를 읽어요. size가 음수면 버퍼 하나 분량. EOF에선 b'' 반환. (3.3)
    • readinto(b): b로 바이트 읽기. 읽은 바이트 수 반환(EOF는 0). (3.3)
    • mode: 읽기는 'rb', 쓰기는 'wb'. (3.13)
    • name: bzip2 파일 이름. 기반 파일 객체의 name과 동등. (3.13)

    (3.10부터 이 클래스는 여러 동시 읽기/쓰기 스레드에 대해 thread unsafe — gzip과 lzma의 동급 클래스와 동일)

증분 (해)압축

  • class bz2.BZ2Compressor(compresslevel=9): 새 컴프레서 객체 생성. 데이터를 증분 압축하는 데 사용. 원샷은 compress() 함수를 대신 사용. compresslevel은 1~9, 기본 9.
    • compress(data): 컴프레서 객체에 데이터 제공. 가능하면 압축된 데이터 청크를 반환하거나 빈 바이트 문자열 반환. 데이터 제공이 끝나면 flush()를 호출해 압축 과정을 마쳐요.
    • flush(): 압축 과정 완료. 내부 버퍼에 남은 압축 데이터 반환. 이 메서드 호출 후 컴프레서 객체는 사용할 수 없어요.
  • class bz2.BZ2Decompressor: 새 디컴프레서 객체 생성. 증분 해제에 사용. 원샷은 decompress() 함수 사용. decompress()BZ2File과 달리 여러 압축 스트림을 포함한 입력을 투명하게 처리하지 않아요. 다중 스트림 입력을 해제하려면 각 스트림마다 새 디컴프레서를 사용해야 해요.
    • decompress(data, max_length=-1): data(bytes-like)를 해제해 압축되지 않은 데이터를 bytes로 반환. 일부 data는 내부 버퍼링될 수 있어요. max_length가 음수가 아니면 최대 그만큼의 해제 데이터 반환. 이 한도에 도달하고 추가 출력이 가능하면 needs_input이 False가 되는데, 이 경우 다음 decompress(b'') 호출로 더 얻을 수 있어요. 모든 입력이 해제·반환되면 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(bytes-like) 압축. compresslevel 1~9, 기본 9. 증분은 BZ2Compressor 사용.
  • bz2.decompress(data): data(bytes-like) 해제. data가 여러 압축 스트림의 연결이면 모두 해제. 증분은 BZ2Decompressor 사용. (3.3에서 다중 스트림 입력 지원)

사용 예제

compress()decompress()로 왕복 압축을 보여주는 예시예요.

>>> import bz2
>>> data = b"Donec rhoncus quis sapien sit amet molestie. ..."
>>> 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():
...     out = out + comp.compress(chunk)
...
>>> out = out + comp.flush()

이 예제는 "비난수" 데이터 스트림(b"z" 청크)을 사용해요. 임의 데이터는 잘 압축되지 않지만, 정렬되고 반복적인 데이터는 보통 높은 압축률을 냅니다.

바이너리 모드로 bzip2 압축 파일 쓰기/읽기:

>>> with bz2.open("myfile.bz2", "wb") as f:
...     unused = f.write(data)
...
>>> with bz2.open("myfile.bz2", "rb") as f:
...     content = f.read()
...
>>> content == data  # Check equality to original object after round-trip
True

더 알아보기 (Learn more)