파일에 데이터를 저장하거나 불러오는 작업이 어렵게 느껴지시나요? 크롤링한 데이터를 파일로 저장하거나, 로그를 기록하거나, 설정 파일을 읽어야 하는 모든 상황에서 파일 입출력은 필수입니다. 이 글에서는 기초부터 실전 활용까지 완벽하게 알려드립니다.
파일 입출력이 필요한 이유
웹 크롤링 데이터 저장, 로그 기록, 설정 파일 관리, 데이터 백업 등 프로그래밍에서 파일 작업은 피할 수 없습니다. 파일 읽기 쓰기를 마스터하면 데이터를 영구적으로 보관하고 언제든 불러올 수 있습니다.
파일 열기의 기본 구조
open() 함수 완전 분석
f = open("새파일.txt", 'w')
f.close()
핵심 구성 요소:
open(): 파일을 여는 함수"새파일.txt": 파일 경로 (상대경로 또는 절대경로)'w': 파일 열기 모드f.close(): 파일 닫기 (메모리 누수 방지)
파일 경로 지정 방법
# 상대 경로 (현재 스크립트 위치 기준)
f = open("새파일.txt", 'w')
# 절대 경로 (Windows)
f = open("C:/doit/새파일.txt", 'w')
f = open("C:\\\\\\\\doit\\\\\\\\새파일.txt", 'w') # 백슬래시 2개
f = open(r"C:\\\\doit\\\\새파일.txt", 'w') # raw string
# 절대 경로 (Mac/Linux)
f = open("/Users/username/새파일.txt", 'w')
# 폴더 없으면 자동 생성
import os
os.makedirs("data", exist_ok=True)
f = open("data/새파일.txt", 'w')
실무 팁: Windows에서는 / 또는 \\\\\\\\를 사용하거나 r 접두사로 raw string을 만드세요.
파일 열기 모드 완전 정리
기본 3가지 모드
| 모드 | 설명 | 파일 없을 때 | 기존 내용 |
|---|---|---|---|
'r' | 읽기 전용 | 오류 발생 | 유지 |
'w' | 쓰기 전용 | 새로 생성 | 모두 삭제 |
'a' | 추가 모드 | 새로 생성 | 끝에 추가 |
읽기 모드 (r)
# 파일이 존재해야 함
f = open("existing.txt", 'r')
content = f.read()
f.close()
print(content)
주의사항: 파일이 없으면 FileNotFoundError가 발생합니다.
쓰기 모드 (w)
# 기존 파일 내용 완전 삭제 후 새로 작성
f = open("새파일.txt", 'w')
f.write("첫 번째 줄입니다.\\\\n")
f.write("두 번째 줄입니다.\\\\n")
f.close()
위험: 기존 파일이 있으면 내용이 모두 지워집니다!
추가 모드 (a)
# 파일 끝에 내용 추가
f = open("로그.txt", 'a')
f.write("2025-10-07 14:30:00 - 새로운 로그\\\\n")
f.close()
로그 작성: 기존 내용을 유지하면서 새 내용을 추가할 때 최적입니다.
고급 파일 모드
텍스트 vs 바이너리 모드
# 텍스트 모드 (기본)
f = open("text.txt", 'w') # 또는 'wt'
# 바이너리 모드 (이미지, 동영상 등)
f = open("image.jpg", 'rb') # 읽기
f = open("file.pdf", 'wb') # 쓰기
바이너리 사용 시나리오: 이미지 다운로드, 파일 복사, 압축 파일 처리
읽기+쓰기 조합 모드
# 읽기 + 쓰기 (파일 존재 필수, 기존 내용 유지)
f = open("data.txt", 'r+')
# 쓰기 + 읽기 (파일 없으면 생성, 기존 내용 삭제)
f = open("data.txt", 'w+')
# 추가 + 읽기 (파일 없으면 생성, 끝에 추가)
f = open("data.txt", 'a+')
실전 활용: 파일을 읽고 수정해야 할 때 사용합니다.
with 문으로 안전하게 파일 다루기
자동으로 파일 닫기
# 기본 방법 (close() 필수)
f = open("파일.txt", 'w')
f.write("내용")
f.close() # 까먹으면 메모리 누수!
# with 문 (권장 방법)
with open("파일.txt", 'w') as f:
f.write("내용")
# 자동으로 close() 실행됨
Best Practice: 항상 with 문을 사용하세요. 예외 발생 시에도 안전하게 파일이 닫힙니다.
with 문의 장점
# 예외 발생 시에도 안전
try:
with open("data.txt", 'r') as f:
content = f.read()
result = 10 / 0 # 에러 발생
except ZeroDivisionError:
print("에러 발생했지만 파일은 자동으로 닫혔습니다")
안정성: 어떤 상황에서도 파일 핸들이 제대로 닫힙니다.
파일 쓰기 완전 정복
write() 메서드
with open("output.txt", 'w', encoding='utf-8') as f:
f.write("첫 번째 줄\\\\n")
f.write("두 번째 줄\\\\n")
f.write("세 번째 줄\\\\n")
주의: write()는 자동 줄바꿈을 하지 않으므로 \\\\n을 직접 추가해야 합니다.
writelines() 메서드
lines = ["라인1\\\\n", "라인2\\\\n", "라인3\\\\n"]
with open("output.txt", 'w', encoding='utf-8') as f:
f.writelines(lines)
효율성: 여러 줄을 한 번에 쓸 때 유용합니다.
크롤링 데이터 저장 예제
# 키워드 크롤링 결과를 파일로 저장
keywords = ["파이썬", "크롤링", "데이터분석", "머신러닝"]
with open("keywords.txt", 'w', encoding='utf-8') as f:
for i, keyword in enumerate(keywords, 1):
f.write(f"{i}. {keyword}\\\\n")
print("✅ 키워드가 파일에 저장되었습니다")
실무 활용: 웹 크롤링으로 수집한 데이터를 텍스트 파일로 백업합니다.
딕셔너리 데이터 저장
keyword_ranks = {
"파이썬": 1,
"크롤링": 2,
"데이터베이스": 3
}
with open("keyword_ranks.txt", 'w', encoding='utf-8') as f:
for keyword, rank in keyword_ranks.items():
f.write(f"{keyword}: {rank}위\\\\n")
구조화 저장: 키-값 쌍을 텍스트로 저장합니다.
파일 읽기 완전 정복
read() – 전체 내용 읽기
with open("data.txt", 'r', encoding='utf-8') as f:
content = f.read()
print(content)
특징: 파일 전체를 하나의 문자열로 읽습니다.
readline() – 한 줄씩 읽기
with open("data.txt", 'r', encoding='utf-8') as f:
line1 = f.readline()
line2 = f.readline()
line3 = f.readline()
print(line1.strip()) # strip()으로 줄바꿈 제거
print(line2.strip())
print(line3.strip())
활용: 특정 줄만 읽어야 할 때 사용합니다.
readlines() – 모든 줄을 리스트로
with open("data.txt", 'r', encoding='utf-8') as f:
lines = f.readlines()
for line in lines:
print(line.strip())
반환값: 각 줄이 요소인 리스트 ['첫줄\\\\n', '둘째줄\\\\n', ...]
반복문으로 한 줄씩 읽기 (권장)
with open("data.txt", 'r', encoding='utf-8') as f:
for line in f:
print(line.strip())
메모리 효율: 대용량 파일도 한 줄씩 처리해 메모리를 적게 사용합니다.
실전 활용 예제
로그 파일 작성
from datetime import datetime
def write_log(message):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] {message}\\\\n"
with open("app.log", 'a', encoding='utf-8') as f:
f.write(log_entry)
# 사용 예시
write_log("애플리케이션 시작")
write_log("데이터베이스 연결 성공")
write_log("크롤링 완료: 100개 데이터 수집")
자동화: 프로그램 실행 내역을 자동으로 기록합니다.
크롤링 데이터 CSV 저장
# 간단한 CSV 쓰기
keywords = [
("파이썬", 1, "google"),
("크롤링", 2, "keyzard"),
("데이터", 3, "zum")
]
with open("keywords.csv", 'w', encoding='utf-8-sig') as f: # 엑셀 호환
f.write("키워드,순위,출처\\\\n") # 헤더
for keyword, rank, source in keywords:
f.write(f"{keyword},{rank},{source}\\\\n")
print("✅ CSV 파일 저장 완료")
Excel 호환: utf-8-sig 인코딩을 사용하면 엑셀에서 한글이 깨지지 않습니다.
설정 파일 읽기/쓰기
# 설정 저장
config = {
"db_host": "localhost",
"db_port": "3306",
"api_key": "your_api_key_here"
}
with open("config.txt", 'w') as f:
for key, value in config.items():
f.write(f"{key}={value}\\\\n")
# 설정 읽기
config_loaded = {}
with open("config.txt", 'r') as f:
for line in f:
key, value = line.strip().split('=')
config_loaded[key] = value
print(config_loaded)
설정 관리: 프로그램 설정을 파일로 관리합니다.
파일 복사 구현
def copy_file(source, destination):
with open(source, 'rb') as src: # 바이너리 읽기
with open(destination, 'wb') as dst: # 바이너리 쓰기
dst.write(src.read())
print(f"✅ {source} → {destination} 복사 완료")
# 사용 예시
copy_file("원본.txt", "복사본.txt")
copy_file("image.jpg", "image_backup.jpg")
바이너리 모드: 이미지, 동영상 등 모든 파일 타입을 복사할 수 있습니다.
대용량 파일 처리
청크 단위로 읽기
def read_large_file(filename, chunk_size=1024):
with open(filename, 'r', encoding='utf-8') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
# 청크 단위로 처리
process_chunk(chunk)
def process_chunk(data):
# 데이터 처리 로직
print(f"처리 중: {len(data)} 바이트")
메모리 절약: 수 GB 파일도 메모리 오버플로 없이 처리합니다.
라인 카운트
def count_lines(filename):
count = 0
with open(filename, 'r', encoding='utf-8') as f:
for line in f:
count += 1
return count
print(f"총 라인 수: {count_lines('large_file.txt')}")
효율적: 파일 전체를 메모리에 올리지 않고 라인 수를 셉니다.
인코딩 문제 해결
한글 깨짐 방지
# 한글 쓰기
with open("한글.txt", 'w', encoding='utf-8') as f:
f.write("안녕하세요 파이썬")
# 한글 읽기
with open("한글.txt", 'r', encoding='utf-8') as f:
content = f.read()
print(content)
필수 옵션: encoding='utf-8'을 항상 명시하세요.
엑셀 호환 인코딩
# CSV 파일 엑셀에서 열 때
with open("data.csv", 'w', encoding='utf-8-sig') as f:
f.write("이름,나이\\\\n")
f.write("김철수,28\\\\n")
Excel 호환: utf-8-sig는 BOM을 추가해 엑셀에서 한글을 정상 표시합니다.
인코딩 자동 감지
import chardet
# 파일 인코딩 확인
with open("unknown.txt", 'rb') as f:
raw_data = f.read()
result = chardet.detect(raw_data)
encoding = result['encoding']
print(f"감지된 인코딩: {encoding}")
# 올바른 인코딩으로 읽기
with open("unknown.txt", 'r', encoding=encoding) as f:
content = f.read()
오래된 파일: 인코딩을 모를 때 자동으로 감지합니다.
파일 존재 확인 및 예외 처리
안전한 파일 읽기
import os
def safe_read_file(filename):
# 파일 존재 확인
if not os.path.exists(filename):
print(f"❌ 파일 없음: {filename}")
return None
try:
with open(filename, 'r', encoding='utf-8') as f:
return f.read()
except PermissionError:
print(f"❌ 권한 없음: {filename}")
return None
except UnicodeDecodeError:
print(f"❌ 인코딩 오류: {filename}")
return None
except Exception as e:
print(f"❌ 예상치 못한 오류: {e}")
return None
content = safe_read_file("data.txt")
if content:
print(content)
견고성: 모든 예외 상황을 처리해 프로그램이 멈추지 않습니다.
파일 정보 확인
import os
filename = "data.txt"
if os.path.exists(filename):
print(f"파일 크기: {os.path.getsize(filename)} 바이트")
print(f"절대 경로: {os.path.abspath(filename)}")
print(f"수정 시간: {os.path.getmtime(filename)}")
else:
print("파일이 존재하지 않습니다")
메타 정보: 파일 처리 전 상태를 확인합니다.
JSON 파일 다루기
JSON 저장 (웹 크롤링 데이터)
import json
keywords_data = {
"collected_at": "2025-10-07",
"keywords": [
{"keyword": "파이썬", "rank": 1, "source": "google"},
{"keyword": "크롤링", "rank": 2, "source": "keyzard"}
]
}
# JSON 파일로 저장
with open("keywords.json", 'w', encoding='utf-8') as f:
json.dump(keywords_data, f, ensure_ascii=False, indent=2)
print("✅ JSON 저장 완료")
구조화 데이터: 복잡한 데이터 구조를 그대로 저장합니다.
JSON 읽기
import json
with open("keywords.json", 'r', encoding='utf-8') as f:
data = json.load(f)
print(f"수집 일자: {data['collected_at']}")
for item in data['keywords']:
print(f"{item['keyword']}: {item['rank']}위")
API 연동: JSON은 웹 API와 데이터 교환에 표준입니다.
임시 파일 활용
tempfile 모듈
import tempfile
# 임시 파일 생성
with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as tmp:
tmp.write("임시 데이터")
tmp_path = tmp.name
print(f"임시 파일 경로: {tmp_path}")
# 임시 파일 읽기
with open(tmp_path, 'r', encoding='utf-8') as f:
print(f.read())
# 수동 삭제
import os
os.remove(tmp_path)
테스트 코드: 테스트 중 임시 파일이 필요할 때 유용합니다.
파일 시스템 작업
폴더 생성 및 파일 저장
import os
# 폴더 생성 (이미 존재해도 에러 없음)
os.makedirs("data/logs", exist_ok=True)
# 파일 저장
with open("data/logs/app.log", 'w', encoding='utf-8') as f:
f.write("로그 내용")
print("✅ 폴더 및 파일 생성 완료")
자동화: 필요한 폴더 구조를 자동으로 생성합니다.
파일 목록 가져오기
import os
# 현재 폴더의 모든 txt 파일
txt_files = [f for f in os.listdir('.') if f.endswith('.txt')]
for filename in txt_files:
print(f"발견: {filename}")
배치 처리: 여러 파일을 한 번에 처리할 때 사용합니다.
마치며
파이썬 파일 읽기 쓰기는 open() 함수와 3가지 기본 모드(r, w, a)를 이해하면 시작할 수 있습니다. with 문으로 안전하게 파일을 다루고, 인코딩을 명시하며, 예외 처리를 추가하면 실무급 코드가 됩니다.
크롤링 데이터 저장, 로그 기록, 설정 파일 관리 등 다양한 실전 예제를 활용해보세요. 파일 입출력 마스터는 데이터 영속성 확보의 첫걸음입니다.
참고 자료
- Python 공식 문서 – 파일 입출력: https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
- Real Python 파일 가이드: https://realpython.com/read-write-files-python/
- 인코딩 이해하기: https://docs.python.org/3/howto/unicode.html