3강. QTextStream으로 텍스트 파일 다루기

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 모듈에 포함되어 있습니다.
- PySide6 QTextStream 공식 문서
- PySide6 QFile 공식 문서
- PySide6 QIODevice 공식 문서
- Qt for Python File and Datastream Functions
참고: 다음 강의에서는 콘솔에서 만든 QFile과 QTextStream 코드를 GUI 버튼에 연결하는 준비 단계로 넘어갑니다.