io — 스트림 작업을 위한 핵심 도구

io — 스트림 작업을 위한 핵심 도구

io 모듈은 파일 입력·출력(파일 I/O)을 다루는 Python의 주요 인터페이스를 제공해요. 여기에는 텍스트, 바이너리, 그리고 원시(raw) 스트림을 만들고 다루는 클래스들이 들어 있어요. 파이썬의 내장 open() 함수가 돌려주는 파일 객체들이 바로 이 모듈의 클래스들로 구현돼 있습니다.

io는 세 가지 주요 분류의 스트림을 다뤄요:

  • 텍스트 스트림(Text I/O) — 텍스트를 str로 읽고 씁니다. 인코딩/디코딩을 처리해요.
  • 바이너리 스트림(Binary I/O) — 데이터를 bytes 객체로 다룹니다.
  • 원시 스트림(Raw I/O) — 바이트를 블록 기반으로, 인코딩 없이 다룹니다 (저수준).

출처: Python 표준 라이브러리

open()

  • io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

이 함수는 내장 open() 함수의 별칭입니다. file이 경로 문자열이면 해당 파일을 열고, 파일 객체면 그대로 사용합니다.

mode는 텍스트/바이너리를 결정해요:

  • 텍스트 모드: 'r', 'w', 'a', 'x' (그리고 '+' 조합)
  • 바이너리 모드: 'rb', 'wb', 'ab', 'xb'
  • 't'는 텍스트, 'b'는 바이너리, '+'는 읽기/쓰기 모두를 의미합니다.

encoding은 텍스트 모드에서 인코딩을 지정하고, newline은 줄바꿈 처리 방식을, errors는 인코딩 오류 처리 방식을 정해요.

클래스 계층

스트림 클래스는 크게 네 추상 기본 클래스로 나뉩니다:

IOBase

  • class io.IOBase — 모든 I/O 클래스의 추상 기본 클래스. read(), readline(), write(), seek(), tell(), close(), closed, flush(), fileno() 등을 제공해요.

RawIOBase

  • class io.RawIOBase — 원시 바이너리 I/O의 기본 클래스. read(n), readall(), readinto(b), write(b) 등을 정의해요.

BufferedIOBase

  • class io.BufferedIOBase — 버퍼링된 바이너리 I/O의 기본 클래스. read1(), peek() 같은 추가 바이너리 작업을 제공해요.

TextIOBase

  • class io.TextIOBase — 텍스트 I/O의 기본 클래스. read(s), readline(), write(s), encoding, newlines 등을 제공해요.

바이너리 스트림

  • io.BytesIO(initial_bytes=b'') — 메모리의 바이너리 스트림. 파일처럼 동작하지만 메모리 버퍼를 사용해요.
>>> from io import BytesIO
>>> f = BytesIO(b"hello world")
>>> f.read(5)
b'hello'
>>> f.getvalue()
b'hello world'
  • io.BufferedRandom(raw) — 읽기/쓰기가 모두 가능한 버퍼링된 바이너리 스트림.
  • io.BufferedReader(raw), io.BufferedWriter(raw) — 읽기/쓰기 전용 버퍼링 스트림.

텍스트 스트림

  • io.StringIO(initial_value='', newline='\n') — 메모리의 텍스트 스트림. 문자열을 파일처럼 다뤄요.
>>> from io import StringIO
>>> f = StringIO("hello")
>>> f.read()
'hello'
  • io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, ...) — 바이너리 버퍼 위에 텍스트 인코딩/디코딩 계층을 씌우는 클래스. open()이 텍스트 모드로 돌려주는 객체입니다.
  • io.TextIOBase 서브클래스들은 encoding, errors, newlines 속성을 가져요.

성능과 권장 사용

open()은 버퍼링을 자동으로 선택합니다. 텍스트 모드는 버퍼링된 텍스트 스트림을, 바이너리 모드는 버퍼링된 바이너리 스트림을, buffering=0이면 원시 스트림을 돌려줘요.

일반적인 원칙:

  • 텍스트 파일에는 텍스트 스트림을,
  • 바이너리 데이터에는 바이너리 스트림을 사용하세요.
  • StringIO/BytesIO는 메모리 안에서 파일처럼 작업할 때 유용합니다.

예제

파일에 여러 줄 쓰고 다시 읽기:

with open('example.txt', 'w', encoding='utf-8') as f:
    f.write("Hello\nWorld\n")

with open('example.txt', 'r', encoding='utf-8') as f:
    for line in f:
        print(line.strip())

메모리 버퍼를 파일처럼 사용:

from io import StringIO

buf = StringIO()
buf.write("line1\n")
buf.write("line2\n")
buf.seek(0)
print(buf.readlines())  # ['line1\n', 'line2\n']

더 알아보기

  • Python의 내장 open() 함수 문서
  • Python 표준 라이브러리의 os 모듈 (저수준 파일 설명자)
  • Python 공식 문서: io