0. 학습 목표

→ QTextStream으로 텍스트 파일을 더 편하게 쓰고 읽는 방법을 익힙니다.

더보기

이번 글에서 다룰 내용

이번 글에서는 QTextStream큐_텍스트_스트림을 사용해서 텍스트 파일을 다루는 방법을 학습합니다.

1강에서는 QFile로 파일을 쓰고 읽는 가장 간단한 실습을 했습니다.

2강에서는 QFile.open()에 들어가는 QIODevice 플래그를 비교했습니다.

이번 3강에서는 QTextStream을 중심으로 문자열 쓰기, 전체 읽기, 줄 단위 읽기를 실습합니다.

구분 내용
핵심 개념 QTextStream은 열린 파일에 텍스트를 쓰고 읽기 쉽게 도와주는 도구입니다.
실습 준비 Python과 PySide6가 설치된 환경에서 콘솔 스크립트로 실습합니다.
최종 목표 QTextStream으로 텍스트 쓰기, 전체 읽기, 줄 단위 읽기 패턴을 익힙니다.

이번 단계의 핵심: QFile은 파일을 열고 닫는 역할이고, QTextStream은 열린 파일 안에 텍스트를 쓰고 읽는 통로 역할입니다.

 

1. 문자열을 파일에 바로 쓰기 어려운 이유

→ QTextStream이 왜 필요한지 QFile.write() 방식과 비교하며 확인합니다.

더보기

1.1 QFile만 사용하면 불편한 점

QFile만으로도 파일을 열고 데이터를 쓸 수 있습니다.

하지만 QFile.write()는 기본적으로 바이트 데이터를 쓰는 방식입니다.

그래서 문자열을 바로 넣기보다는 인코딩해서 바이트로 바꿔야 합니다.

# qfile_write_bytes.py

from PySide6.QtCore import QFile, QIODevice

file = QFile("stream_test.txt")

if file.open(QIODevice.OpenModeFlag.WriteOnly | QIODevice.OpenModeFlag.Text):
    file.write("첫 번째 줄입니다.\\n".encode("utf-8"))
    file.write("두 번째 줄입니다.".encode("utf-8"))
    file.close()

    print("파일 쓰기 완료!")
else:
    print("파일을 열 수 없습니다.")
    print(file.errorString())

이 방식도 동작은 합니다.

하지만 매번 encode("utf-8")을 써야 해서 초보자에게는 조금 불편합니다.

불편한 부분 설명
문자열 변환 문자열을 파일에 쓰기 전에 bytes로 변환해야 합니다.
코드 가독성 텍스트를 쓰는 코드인데 encode()가 반복되어 흐름이 복잡해 보입니다.
텍스트 처리 줄 단위 읽기, 전체 읽기 같은 텍스트 중심 작업은 QTextStream이 더 자연스럽습니다.

 

1.2 QTextStream을 사용하면 달라지는 점

QTextStream을 사용하면 문자열을 더 자연스럽게 파일에 쓸 수 있습니다.

열린 QFile을 QTextStream에 연결한 뒤, stream에 문자열을 흘려보내면 됩니다.

stream = QTextStream(file)
stream << "첫 번째 줄입니다.\\n"
stream << "두 번째 줄입니다."

이 코드는 문자열을 직접 쓰는 느낌이라 읽기 쉽습니다.

공식 문서에서도 QTextStream은 텍스트를 읽고 쓰기 위한 편리한 인터페이스라고 설명합니다.

도구 역할
QFile 파일을 열고 닫습니다.
QTextStream 열린 파일에 텍스트를 쓰고 읽습니다.
stream << "문자열" 문자열을 파일에 씁니다.
readAll() 텍스트 전체를 한 번에 읽습니다.
readLine() 텍스트를 한 줄씩 읽습니다.

문제의 핵심: 텍스트 파일을 다룰 때는 QFile만 사용하는 것보다 QTextStream을 함께 사용하는 편이 더 읽기 쉽고 편합니다.

 

2. QTextStream으로 쓰고 읽어보기

→ QTextStream으로 텍스트를 저장하고, 전체 내용과 줄 단위 내용을 읽어 봅니다.

더보기

2.1 QTextStream으로 텍스트 쓰기

먼저 QTextStream으로 텍스트 파일을 만들어 보겠습니다.

아래 코드를 text_stream_write.py로 저장하고 실행합니다.

# text_stream_write.py

from PySide6.QtCore import QFile, QIODevice, QTextStream

file = QFile("stream_test.txt")

if file.open(QIODevice.OpenModeFlag.WriteOnly | QIODevice.OpenModeFlag.Text):
    stream = QTextStream(file)
    stream << "사과\\n"
    stream << "바나나\\n"
    stream << "포도\\n"
    file.close()

    print("QTextStream으로 파일 쓰기 완료!")
else:
    print("파일을 열 수 없습니다.")
    print(file.errorString())

실행하면 현재 폴더에 stream_test.txt 파일이 만들어집니다.

파일 안에는 아래와 같은 텍스트가 저장됩니다.

사과
바나나
포도

 

2.2 readAll()로 전체 내용 읽기

이번에는 방금 만든 파일 전체를 한 번에 읽어 봅니다.

전체 내용을 한 번에 읽을 때는 readAll()을 사용합니다.

# text_stream_read_all.py

from PySide6.QtCore import QFile, QIODevice, QTextStream

file = QFile("stream_test.txt")

if file.open(QIODevice.OpenModeFlag.ReadOnly | QIODevice.OpenModeFlag.Text):
    stream = QTextStream(file)
    content = stream.readAll()
    file.close()

    print("전체 내용:")
    print(content)
else:
    print("파일을 읽을 수 없습니다.")
    print(file.errorString())

실행하면 파일 전체 내용이 콘솔에 출력됩니다.

전체 내용:
사과
바나나
포도

파일 크기가 작을 때는 readAll()이 간단하고 편합니다.

 

2.3 readLine()으로 한 줄씩 읽기

이번에는 파일을 한 줄씩 읽어 봅니다.

한 줄씩 처리하고 싶을 때는 readLine()을 사용할 수 있습니다.

# text_stream_read_line.py

from PySide6.QtCore import QFile, QIODevice, QTextStream

file = QFile("stream_test.txt")

if file.open(QIODevice.OpenModeFlag.ReadOnly | QIODevice.OpenModeFlag.Text):
    stream = QTextStream(file)

    print("줄 단위 읽기:")

    while not stream.atEnd():
        line = stream.readLine()
        print(f"- {line}")

    file.close()
else:
    print("파일을 읽을 수 없습니다.")
    print(file.errorString())

실행하면 파일 내용이 한 줄씩 출력됩니다.

줄 단위 읽기:
- 사과
- 바나나
- 포도

줄마다 따로 처리해야 할 때는 readLine() 방식이 더 좋습니다.

핵심 확인: readAll()은 전체 내용을 한 번에 읽고, readLine()은 한 줄씩 읽습니다.

 

3. QTextStream 코드 흐름 자세히 살펴보기

→ QTextStream이 QFile과 연결되어 텍스트를 처리하는 흐름을 분석합니다.

더보기

3.1 QTextStream 쓰기 흐름

QTextStream으로 파일에 텍스트를 쓰는 흐름은 다음과 같습니다.

QFile 객체 생성
    ↓
WriteOnly + Text 모드로 파일 열기
    ↓
QTextStream을 QFile에 연결
    ↓
stream << "문자열"로 텍스트 쓰기
    ↓
파일 닫기

여기서 중요한 점은 QTextStream이 혼자 파일을 여는 것이 아니라는 점입니다.

먼저 QFile로 파일을 열고, 그 열린 파일을 QTextStream에 연결합니다.

코드 역할
file = QFile("stream_test.txt") 파일을 다루기 위한 QFile 객체를 만듭니다.
file.open(...) 파일에 실제로 접근합니다.
stream = QTextStream(file) 열린 파일에 텍스트 통로를 연결합니다.
stream << "사과\\n" 텍스트를 파일에 씁니다.
file.close() 파일 사용을 끝내고 닫습니다.

 

3.2 QTextStream 읽기 흐름

QTextStream으로 파일을 읽는 흐름도 비슷합니다.

파일을 읽기 모드로 열고, QTextStream으로 내용을 가져옵니다.

QFile 객체 생성
    ↓
ReadOnly + Text 모드로 파일 열기
    ↓
QTextStream을 QFile에 연결
    ↓
readAll() 또는 readLine()으로 읽기
    ↓
파일 닫기
읽기 방식 사용 상황
readAll() 파일 전체 내용을 한 번에 읽고 싶을 때 사용합니다.
readLine() 파일을 한 줄씩 처리하고 싶을 때 사용합니다.
atEnd() 더 읽을 내용이 남아 있는지 확인할 때 사용합니다.

 

3.3 초보자가 헷갈릴 수 있는 부분

처음에는 QFile과 QTextStream의 역할이 섞여 보일 수 있습니다.

둘의 역할을 분리해서 기억하면 훨씬 쉽습니다.

헷갈리는 부분 정리
QTextStream이 파일을 여는가? 아닙니다. 파일은 QFile.open()으로 열고, QTextStream은 열린 파일에 연결됩니다.
readAll()과 readLine()은 언제 쓰는가? 전체를 한 번에 읽을 때는 readAll(), 한 줄씩 처리할 때는 readLine()을 사용합니다.
file.close()는 꼭 필요한가? 파일 작업이 끝나면 닫는 습관을 들이는 것이 좋습니다.
Text 플래그는 왜 붙이는가? 텍스트 파일로 다루겠다는 의미를 명확히 하기 위해 함께 사용합니다.

주의할 점: QTextStream은 내부적으로 버퍼를 사용할 수 있으므로, 파일 위치를 다시 옮겨야 하는 고급 상황에서는 QFile.reset()보다 stream.seek() 같은 스트림 기준 동작을 고려해야 합니다.

 

4. QFile.write()와 QTextStream 비교하며 정리하기

→ 바이트 중심 방식과 텍스트 스트림 방식을 비교하고 핵심을 정리합니다.

더보기

4.1 QFile.write()와 QTextStream 비교

QFile.write()와 QTextStream은 둘 다 파일에 내용을 쓸 수 있습니다.

하지만 텍스트 파일을 다룰 때는 QTextStream이 더 자연스럽습니다.

구분 QFile.write() QTextStream
중심 개념 바이트 데이터 쓰기 텍스트 데이터 쓰기와 읽기
문자열 쓰기 문자열을 encode()로 변환해야 할 수 있습니다. stream << "문자열" 형태로 쓸 수 있습니다.
전체 읽기 직접 바이트를 읽고 문자열로 바꿔야 할 수 있습니다. readAll()로 전체 텍스트를 읽을 수 있습니다.
줄 단위 읽기 직접 처리해야 할 부분이 많습니다. readLine()으로 한 줄씩 읽을 수 있습니다.
추천 상황 바이너리 데이터나 직접 바이트를 다루는 상황 텍스트 파일을 다루는 상황

 

4.2 최종 정리

이번 글에서는 QTextStream으로 텍스트 파일을 다루는 기본 패턴을 실습했습니다.

핵심 내용 정리
문제 파악 QFile.write()만 사용하면 문자열을 bytes로 변환해야 해서 불편할 수 있음을 확인했습니다.
문제 해결 QTextStream으로 문자열 쓰기, 전체 읽기, 줄 단위 읽기를 실습했습니다.
코드 분석 QFile은 파일을 열고 닫고, QTextStream은 텍스트를 쓰고 읽는 통로 역할을 한다는 것을 살펴봤습니다.
비교 정리 바이트 중심 작업은 QFile.write(), 텍스트 중심 작업은 QTextStream이 더 적합하다는 것을 정리했습니다.

기억할 문장: QTextStream은 열린 QFile 위에서 텍스트를 편하게 쓰고 읽게 해주는 통로입니다.

 

참고. 공식 문서로 확인하기

→ QTextStream과 관련된 자세한 내용은 공식 문서에서 확인합니다.

더보기

참고 문서

이번 글에서 사용한 QTextStream, QFile, QIODevice는 PySide6의 QtCore 모듈에 포함되어 있습니다.

참고: 다음 강의에서는 콘솔에서 만든 QFile과 QTextStream 코드를 GUI 버튼에 연결하는 준비 단계로 넘어갑니다.