Skip to content

Latest commit

 

History

History

P_08_FileIO

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

README.md

Python 파일 입출력 (File I/O) 완벽 가이드

목차

  1. 파일 입출력 개요
  2. CSV와 TSV 파일
  3. 파일 열기 모드
  4. 파일 읽기
  5. 파일 쓰기와 추가
  6. with 구문
  7. csv 모듈 사용
  8. 인코딩 (Encoding)
  9. 실용적인 예제
  10. 디렉토리 작업

1. 파일 입출력 개요

1.1 파일 입출력의 기본 개념

파일 입출력(File I/O)은 프로그램에서 파일을 읽거나 쓰는 작업을 말합니다.

프로그램 <--읽기(Read)--> 파일
프로그램 --쓰기(Write)--> 파일

1.2 기본 사용 패턴

# 파일 열기 -> 작업 -> 닫기
파일객체 = open(파일이름, 파일열기모드)
# 파일 사용 (읽기 또는 쓰기)
파일객체.close()  # 반드시 닫아야 함!

2. CSV와 TSV 파일

2.1 CSV (Comma Separated Value)

데이터가 **쉼표(,)**로 구분된 포맷입니다.

Name,Age,City
Alice,25,New York
Bob,30,London

2.2 TSV (Tab Separated Value)

데이터가 **탭(\t)**으로 구분된 포맷입니다.

Name	Age	City
Alice	25	New York
Bob	30	London

2.3 CSV vs TSV 비교

항목 CSV TSV
구분자 쉼표 (,) 탭 (\t)
확장자 .csv .tsv
장점 범용적, Excel 호환 데이터에 쉼표 포함 가능
단점 데이터에 쉼표 포함 시 따옴표 필요 시각적 정렬이 어려움
용도 일반 데이터 텍스트 데이터, 로그

3. 파일 열기 모드

3.1 기본 모드

모드 설명 파일 없을 때 기존 내용
r 읽기 모드 FileNotFoundError 유지
w 쓰기 모드 새로 생성 덮어쓰기
a 추가 모드 새로 생성 유지 (끝에 추가)
x 배타적 생성 새로 생성 FileExistsError (파일 있으면)

3.2 바이너리 모드

모드 설명
rb 바이너리 읽기
wb 바이너리 쓰기
ab 바이너리 추가

3.3 읽기+쓰기 모드

모드 설명
r+ 읽기+쓰기 (파일 있어야 함)
w+ 쓰기+읽기 (기존 내용 삭제)
a+ 추가+읽기 (끝에 추가)

3.4 모드 사용 예시

# 읽기 모드 - 파일이 없으면 에러
f = open("data.txt", "r")

# 쓰기 모드 - 기존 내용 삭제됨
f = open("data.txt", "w")

# 추가 모드 - 기존 내용 뒤에 추가
f = open("data.txt", "a")

# 바이너리 모드 - 이미지, 동영상 등
f = open("image.png", "rb")

4. 파일 읽기

4.1 readline() - 한 줄씩 읽기

파일에서 한 줄씩 읽어옵니다.

f = open("새파일.txt", "r")

line = f.readline()
print(line)  # 첫 번째 줄

line = f.readline()
print(line)  # 두 번째 줄

f.close()

4.2 read() - 전체 읽기

파일 전체 내용을 문자열로 읽어옵니다.

f = open("새파일.txt", "r")

data = f.read()  # 전체 내용을 하나의 문자열로
print(data)

f.close()

4.3 read(size) - 지정된 크기만큼 읽기

f = open("새파일.txt", "r")

chunk = f.read(100)  # 100자만 읽기
print(chunk)

f.close()

4.4 readlines() - 전체를 리스트로 읽기

모든 줄을 리스트로 반환합니다.

f = open("새파일.txt", "r")

lines = f.readlines()  # ['줄1\n', '줄2\n', '줄3\n', ...]
for line in lines:
    print(line, end="")

f.close()

4.5 반복문으로 읽기 (권장)

메모리 효율적인 방법입니다.

# while 반복문
f = open("새파일.txt", "r")

while True:
    line = f.readline()
    if not line:  # 더 이상 읽을 줄이 없으면 종료
        break
    print(line, end="")  # 자동으로 추가되는 줄바꿈 제거

f.close()
# for 반복문 (가장 권장)
f = open("새파일.txt", "r")

for line in f:  # 파일 객체는 iterable
    print(line, end="")

f.close()

4.6 읽기 메서드 비교

메서드 반환 타입 특징 메모리
read() 문자열 전체 내용 많이 사용
read(n) 문자열 n자만 읽기 효율적
readline() 문자열 한 줄 효율적
readlines() 리스트 모든 줄 많이 사용
for line in f 반복자 한 줄씩 가장 효율적

5. 파일 쓰기와 추가

5.1 write() - 문자열 쓰기

# 쓰기 모드 (w) - 기존 내용 삭제
f = open("새파일.txt", "w")

for i in range(1, 6):
    f.write(f"{i} Line\n")  # 줄바꿈은 직접 추가해야 함

f.close()

# 결과:
# 1 Line
# 2 Line
# 3 Line
# 4 Line
# 5 Line

5.2 추가 모드 (a)

# 추가 모드 (a) - 기존 내용 뒤에 추가
f = open("새파일.txt", "a")

for i in range(6, 11):
    f.write(f"{i} Line append\n")

f.close()

# 기존 내용 뒤에 추가됨:
# 1 Line
# 2 Line
# ...
# 6 Line append
# 7 Line append
# ...

5.3 writelines() - 리스트 쓰기

f = open("새파일.txt", "w")

lines = ["첫 번째 줄\n", "두 번째 줄\n", "세 번째 줄\n"]
f.writelines(lines)  # 리스트의 각 요소를 파일에 씀

f.close()

5.4 print() 함수로 파일 쓰기

f = open("새파일.txt", "w")

print("Hello, World!", file=f)  # file 매개변수로 출력 대상 지정
print("Python is fun!", file=f)

f.close()

6. with 구문

6.1 with 구문의 장점

  • close()를 자동 호출
  • 예외 발생 시에도 파일이 안전하게 닫힘
  • 코드가 더 간결하고 안전함

6.2 기본 사용법

# with 구문 사용 (권장)
with open("새파일.txt", "r") as f:
    data = f.read()
    print(data)
# 블록을 벗어나면 자동으로 f.close() 호출

# 기존 방식 (비권장)
f = open("새파일.txt", "r")
try:
    data = f.read()
    print(data)
finally:
    f.close()

6.3 파일 읽기 with 구문

# 전체 읽기
with open("새파일.txt", "r") as f:
    data = f.read()
    print(data)

# 줄 단위 읽기
with open("새파일.txt", "r") as f:
    for line in f:
        print(line, end="")

6.4 파일 쓰기 with 구문

with open("새파일.txt", "w") as f:
    for i in range(1, 11):
        f.write(f"{i} 번째 줄입니다.\n")

6.5 여러 파일 동시 열기

# 두 파일을 동시에 열기
with open("input.txt", "r") as infile, open("output.txt", "w") as outfile:
    for line in infile:
        outfile.write(line.upper())  # 대문자로 변환하여 저장

7. csv 모듈 사용

7.1 csv 모듈 import

import csv

7.2 CSV 파일 쓰기

import csv

data = [
    ["Name", "Age", "City"],
    ["Alice", 25, "New York"],
    ["Bob", 30, "London"],
    ["Charlie", 35, "Paris"]
]

with open("data.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerows(data)  # 여러 행 한번에 쓰기

# 결과 파일 (data.csv):
# Name,Age,City
# Alice,25,New York
# Bob,30,London
# Charlie,35,Paris

7.3 CSV 파일 읽기

import csv

with open("data.csv", "r") as file:
    reader = csv.reader(file)
    for row in reader:
        print(row)

# 출력:
# ['Name', 'Age', 'City']
# ['Alice', '25', 'New York']
# ['Bob', '30', 'London']
# ['Charlie', '35', 'Paris']

7.4 한 행씩 쓰기

import csv

with open("data.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(["Name", "Age", "City"])  # 헤더
    writer.writerow(["Alice", 25, "New York"])
    writer.writerow(["Bob", 30, "London"])

7.5 TSV 파일 작업

import csv

# TSV 쓰기
with open("data.tsv", "w", newline="") as file:
    writer = csv.writer(file, delimiter="\t")  # 탭을 구분자로 지정
    writer.writerow(["Name", "Age", "City"])
    writer.writerow(["Alice", 25, "New York"])
    writer.writerow(["Bob", 30, "London"])

# TSV 읽기
with open("data.tsv", "r") as file:
    reader = csv.reader(file, delimiter="\t")
    for row in reader:
        print(row)

7.6 딕셔너리로 CSV 다루기

import csv

# DictWriter - 딕셔너리로 쓰기
data = [
    {"Name": "Alice", "Age": 25, "City": "New York"},
    {"Name": "Bob", "Age": 30, "City": "London"}
]

with open("data.csv", "w", newline="") as file:
    fieldnames = ["Name", "Age", "City"]
    writer = csv.DictWriter(file, fieldnames=fieldnames)

    writer.writeheader()  # 헤더 쓰기
    writer.writerows(data)  # 데이터 쓰기
import csv

# DictReader - 딕셔너리로 읽기
with open("data.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        print(row)
        # {'Name': 'Alice', 'Age': '25', 'City': 'New York'}
        print(f"이름: {row['Name']}, 나이: {row['Age']}")

7.7 csv 모듈 주요 매개변수

매개변수 설명 기본값
delimiter 필드 구분자 ,
quotechar 인용 문자 "
quoting 인용 방식 QUOTE_MINIMAL
lineterminator 줄 종료 문자 \r\n
import csv

# 커스텀 구분자와 인용 문자
with open("data.csv", "w", newline="") as file:
    writer = csv.writer(file, delimiter=';', quotechar="'")
    writer.writerow(["Name", "Description"])
    writer.writerow(["Python", "A programming language"])

8. 인코딩 (Encoding)

8.1 인코딩이란?

문자를 컴퓨터가 이해할 수 있는 바이트로 변환하는 방식입니다.

8.2 주요 인코딩 방식

인코딩 바이트 수 주요 사용처 특징
UTF-8 가변 (1~4) Mac, Linux, 웹 국제 표준, 영어 1바이트, 한글 3바이트
CP949 가변 (1~2) Windows (한글) 한글 Windows 기본, 한글 2바이트
EUC-KR 가변 (1~2) 레거시 시스템 CP949의 부분집합
ASCII 1 영문 전용 영어, 숫자, 특수문자만

8.3 운영체제별 기본 인코딩

운영체제 기본 인코딩
Windows (한글) CP949
Mac UTF-8
Linux UTF-8

8.4 인코딩 지정하기

# UTF-8로 파일 읽기 (Mac/Linux 기본)
with open("파일.txt", "r", encoding="utf-8") as f:
    data = f.read()

# CP949로 파일 읽기 (Windows 한글)
with open("파일.txt", "r", encoding="cp949") as f:
    data = f.read()

# UTF-8로 파일 쓰기
with open("파일.txt", "w", encoding="utf-8") as f:
    f.write("안녕하세요")

8.5 인코딩 에러 처리

# 에러 무시
with open("파일.txt", "r", encoding="utf-8", errors="ignore") as f:
    data = f.read()

# 에러 문자 대체
with open("파일.txt", "r", encoding="utf-8", errors="replace") as f:
    data = f.read()  # 읽을 수 없는 문자는 ?로 대체

8.6 인코딩 자동 감지

# chardet 라이브러리 사용 (pip install chardet)
import chardet

with open("파일.txt", "rb") as f:
    result = chardet.detect(f.read())
    print(result)
    # {'encoding': 'utf-8', 'confidence': 0.99, 'language': ''}

# 감지된 인코딩으로 읽기
with open("파일.txt", "r", encoding=result['encoding']) as f:
    data = f.read()

8.7 크로스 플랫폼 팁

# 권장: 항상 UTF-8 명시
with open("파일.txt", "w", encoding="utf-8") as f:
    f.write("크로스 플랫폼 호환 파일")

# CSV 파일도 마찬가지
import csv
with open("data.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["이름", "나이"])

9. 실용적인 예제

9.1 설정 파일 읽기

def read_config(filename):
    """key=value 형식의 설정 파일 읽기"""
    config = {}
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#"):  # 빈 줄과 주석 제외
                key, value = line.split("=", 1)
                config[key.strip()] = value.strip()
    return config

# config.txt:
# host=localhost
# port=8080
# debug=true

config = read_config("config.txt")
print(config)
# {'host': 'localhost', 'port': '8080', 'debug': 'true'}

9.2 로그 파일 분석

def count_errors(log_file):
    """로그 파일에서 에러 횟수 계산"""
    error_count = 0
    with open(log_file, "r", encoding="utf-8") as f:
        for line in f:
            if "ERROR" in line:
                error_count += 1
    return error_count

errors = count_errors("app.log")
print(f"총 에러 수: {errors}")

9.3 파일 복사

def copy_file(src, dst):
    """파일 복사 (텍스트)"""
    with open(src, "r", encoding="utf-8") as infile:
        with open(dst, "w", encoding="utf-8") as outfile:
            outfile.write(infile.read())

def copy_file_binary(src, dst):
    """파일 복사 (바이너리 - 이미지 등)"""
    with open(src, "rb") as infile:
        with open(dst, "wb") as outfile:
            outfile.write(infile.read())

9.4 대용량 파일 처리

def process_large_file(filename, chunk_size=1024*1024):
    """대용량 파일을 청크 단위로 처리"""
    with open(filename, "r", encoding="utf-8") as f:
        while True:
            chunk = f.read(chunk_size)  # 1MB씩 읽기
            if not chunk:
                break
            # 청크 처리
            process(chunk)

9.5 JSON 파일 다루기

import json

# JSON 쓰기
data = {
    "name": "Alice",
    "age": 25,
    "cities": ["New York", "London"]
}

with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=4)

# JSON 읽기
with open("data.json", "r", encoding="utf-8") as f:
    loaded_data = json.load(f)
    print(loaded_data)

10. 디렉토리 작업

10.1 os 모듈을 사용한 디렉토리 생성

import os

base_path = r"/content/drive/MyDrive/[AI]"
target_dir = os.path.join(base_path, "out")

# 디렉토리 존재 확인 후 생성
if not os.path.exists(target_dir):
    os.mkdir(target_dir)  # 단일 디렉토리 생성
    print("디렉토리 생성 완료")
else:
    print("디렉토리 이미 존재")

# 중첩 디렉토리 생성
nested_dir = os.path.join(base_path, "a/b/c")
os.makedirs(nested_dir, exist_ok=True)  # exist_ok=True: 이미 있어도 에러 없음

10.2 디렉토리 내부에 파일 쓰기

import os

target_dir = "output"
os.makedirs(target_dir, exist_ok=True)

target_file = os.path.join(target_dir, "test.txt")

with open(target_file, "w", encoding="utf-8") as f:
    for i in range(1, 11):
        f.write(f"{i} 번째 줄입니다.\n")

10.3 경로 관련 유용한 함수

import os

path = "/home/user/documents/file.txt"

# 경로 분리
print(os.path.dirname(path))   # /home/user/documents
print(os.path.basename(path))  # file.txt
print(os.path.split(path))     # ('/home/user/documents', 'file.txt')

# 확장자 분리
print(os.path.splitext(path))  # ('/home/user/documents/file', '.txt')

# 절대 경로
print(os.path.abspath("file.txt"))  # /current/working/dir/file.txt

# 경로 결합 (OS에 맞는 구분자 사용)
new_path = os.path.join("folder", "subfolder", "file.txt")
# Windows: folder\subfolder\file.txt
# Linux/Mac: folder/subfolder/file.txt

주요 함수/메서드 요약

파일 열기/닫기

함수/메서드 설명
open(file, mode) 파일 열기
f.close() 파일 닫기
with open() as f: 컨텍스트 관리자 (자동 닫기)

읽기 메서드

메서드 설명
f.read() 전체 읽기
f.read(n) n자 읽기
f.readline() 한 줄 읽기
f.readlines() 전체를 리스트로

쓰기 메서드

메서드 설명
f.write(str) 문자열 쓰기
f.writelines(list) 리스트 쓰기

csv 모듈

함수/객체 설명
csv.reader(f) CSV 읽기 객체
csv.writer(f) CSV 쓰기 객체
csv.DictReader(f) 딕셔너리로 읽기
csv.DictWriter(f) 딕셔너리로 쓰기

참고 자료