파이썬 파일 읽기 쓰기 완벽 가이드

파일에 데이터를 저장하거나 불러오는 작업이 어렵게 느껴지시나요? 크롤링한 데이터를 파일로 저장하거나, 로그를 기록하거나, 설정 파일을 읽어야 하는 모든 상황에서 파일 입출력은 필수입니다. 이 글에서는 기초부터 실전 활용까지 완벽하게 알려드립니다.

파일 입출력이 필요한 이유

웹 크롤링 데이터 저장, 로그 기록, 설정 파일 관리, 데이터 백업 등 프로그래밍에서 파일 작업은 피할 수 없습니다. 파일 읽기 쓰기를 마스터하면 데이터를 영구적으로 보관하고 언제든 불러올 수 있습니다.

파일 열기의 기본 구조

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 문으로 안전하게 파일을 다루고, 인코딩을 명시하며, 예외 처리를 추가하면 실무급 코드가 됩니다.

크롤링 데이터 저장, 로그 기록, 설정 파일 관리 등 다양한 실전 예제를 활용해보세요. 파일 입출력 마스터는 데이터 영속성 확보의 첫걸음입니다.


참고 자료

댓글 남기기