KDT/Python

파일 입출력 라이브러리

jhwannabe 2023. 3. 14. 16:34

1. 파일 읽기 및 저장하기

fileinput

  • 텍스트 파일을 읽고, 쓰고, 저장하는 기능을 편리하게 사용할 수 있도록 해주는 라이브러리
  • 여러개의 파일을 읽어서 수정할 수 있음
import fileinput
import os
import glob

# 현재 경로 확인
os.getcwd()

# 디렉토리 내 파일 확인하기
os.listdir(os.getcwd())

# 경로 설정
path = 'sample/'

# glob(): 해당 경로의 파일 이름을 리스트로 반환
glob.glob(os.path.join(path, '*.txt'))
# ['sample\\새파일1.txt',
#  'sample\\새파일2.txt',
#  'sample\\새파일3.txt',
#  'sample\\새파일4.txt',
#  'sample\\새파일5.txt']


with fileinput.input(glob.glob(os.path.join(path, '*.txt'))) as f:
    for line in f:
        print(line)

# 1번째 줄입니다.
# 2번째 줄입니다.
# 3번째 줄입니다.
# 4번째 줄입니다.
# 5번째 줄입니다.
# 6번째 줄입니다.
# 7번째 줄입니다.
# 8번째 줄입니다.
# 9번째 줄입니다.
# 10번째 줄입니다.
# 11번째 줄입니다.
# 12번째 줄입니다.
# 13번째 줄입니다.
# 14번째 줄입니다.
# 15번째 줄입니다.
txt_files = glob.glob(os.path.join(path, '*.txt'))

with fileinput.input(txt_files, inplace=True) as f:
    for line in f:
        if f.isfirstline(): # 첫번째 라인인지 확인하는 함수(Bool)
            print('첫번째 라인입니다.', end='\n')
        else:
            print(line, end='')
            
            
# 검색된 라인 변경하기
with fileinput.input(txt_files, inplace=True) as f:
    for line in f:
        if line == '첫번째 라인입니다.\n':
            print('1번째 라인입니다.',end='\n')
        else:
            print(line, end='')
            

# 키워드 포함 라인 변경하기
with fileinput.input(txt_files, inplace=True) as f:
    for line in f:
        if '1번째' in line:
            print('첫번째 줄입니다.',end='\n')
        else:
            print(line, end='')


# 텍스트 치환하기
with fileinput.input(txt_files, inplace=True) as f:
    for line in f:
        if '12번째' in line:
            print('첫번째 줄입니다.',end='')
        else:
            print(line, end='')

pickle

파이썬에서 사용하는 딕셔너리, 리스트, 클래스 등의 자료형을 변환없이 그대로 파일로 저장하고 불러올 때 사용하는 모듈

import pickle

data = ['apple', 'banana', 'orange']

# 파일 저장
with open('list.pkl', 'wb') as f:
    pickle.dump(data, f)
    
# 파일 읽기
with open('list.pkl', 'rb') as f:
    data = pickle.load(f)

type(data) # list
print(data) # ['apple', 'banana', 'orange']

# 딕셔너리 저장
data = {}
data[1] = {'id':1, 'userid':'apple', 'name':'김사과','gender':'여자', 'age':20}

with open('dict.pkl', 'wb') as f:
    pickle.dump(data, f)

with open('dic.pkl', 'rb') as f:
    data = pickle.load(f)
    
type(data) # dict
print(data) # {1: {'id': 1, 'userid': 'apple', 'name': '김사과', 'gender': '여자', 'age': 20}}

2. 파일 찾기, 복사, 이동하기

파일 확장자로 찾기

os.getcwd()

for filename in glob.glob('*.txt'):
    print(filename)
    
# txt 파일 찾기: 하위 경로
for filename in glob.glob('**/*.txt'):
    print(filename)
    
# sample\새파일1.txt
# sample\새파일2.txt
# sample\새파일3.txt
# sample\새파일4.txt
# sample\새파일5.txt
# txt 파일 찾기: 현재와 하위 경로 모두 포함
for filename in glob.glob('**/*.txt', recursive=True):
    print(filename)
    
# Jupyter Notebook Installation.txt
# sample\새파일1.txt
# sample\새파일2.txt
# sample\새파일3.txt
# sample\새파일4.txt
# sample\새파일5.txt
# 파일명 글자수로 찾기
for filename in glob.glob('????.*', recursive=True): # 글자수 4개
    print(filename)
    
# dict.pkl
# list.pkl
# 점심시간.txt
    
# 문자열 패턴 포함 파일명 찾기
for filename in glob.glob('[a-z][a-z][a-z][a-z].*', recursive=True): # 알파벳 글자수 4개
    print(filename)
# dict.pkl
# list.pkl

for filename in glob.glob('**/새파일*.*'):
    print(filename)
# sample\새파일1.txt
# sample\새파일2.txt
# sample\새파일3.txt
# sample\새파일4.txt
# sample\새파일5.txt

for filename in glob.glob('**/*프로젝트*.*'):
    print(filename)
# project\25_프로젝트.ipynb
# project\프로젝트 개요.txt

fnmatch

  • glob과 동일하게 특정한 패턴을 따르는 파일명을 찾아주는 모듈
  • 파일명 매칭 여부를 True, False 형태로 반환하기 때문에 os.listdir() 함수와 함께 사용
import fnmatch

# 파일명은 '새' 시작하고 확장명은 .txt를 검색
# 확장자를 제외한 파일명의 길이는 4개이며, 파일명의 마지막 문자는 숫자임
for filename in os.listdir('./sample'):
    if fnmatch.fnmatch(filename,'새??[0-9].txt'):
        print(filename)

# 새파일1.txt
# 새파일2.txt
# 새파일3.txt
# 새파일4.txt
# 새파일5.txt

shutil

  • 파일을 복사하거나 이동할 때 사용하는 내장 모듈
import shutil
  • 파일 복사하기
shutil.copy('./sample/새파일1.txt', './sample/새파일1_복사본.txt')
  • 파일 이동하기
shutil.move('./sample/새파일1_복사본.txt', './새파일1_복사본.txt')
  • 파일 확장명 바꾸기
shutil.move('./새파일1_복사본.txt', './새파일1_복사본.py')

3. 파일 압축하기

데이터 압축

  • 대용량 데이터 및 대량의 파일을 전송 시, 전송 속도가 느리며 전송 문제가 발생할 가능성이 매우 높음
  • 데이터 압축의 종류
    • 손실 압축: 사람이 눈치재지 못할 수준의 정보만 버리고 압축하는 방법
    • 무손실 압축: 데이터 손실이 전혀 없는 압축
  • 압축률: 압축된 자료량(압축된 데이터 크기) / 원시 자료량(원래 데이터 크기)
  • 다양한 압축 알고리즘에 따라 압축 성능 및 시간이 좌우됨
  • 압축 - 인코딩(Encoding) / 압축 해제 - 디코딩(Decoding)

zlib

  • 데이터를 압축하거나 해제할 때 사용하는 모듈
  • compress()와 decompres()로 문자열을 압축하거나 해제
  • 데이터 크기를 줄여서 전송이 필요한 경우 사용
import zlib

data = 'Hello Python!' * 10000
data
print(len(data)) # 130000 bytes

compress_data = zlib.compress(data.encode(encoding='utf-8'))
print(len(compress_data)) # 293 bytes

compress_data
# b'x\x9c\xed\xc71\r\x00 \x0c\x000+\xe0f\'&H8\x16\xf6\xf0\xe0\x1e\x1f\xa4\xfd\x1a3\xb3\xda\xb8g\xd5\xee!"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""?\xe6\x01le79'

org_data = zlib.decompress(compress_data).decode('utf-8')
print(len(org_data)) # 13000 bytes

gzip

  • 파일을 압축하거나 해제할 때 사용하는 모듈
  • 내부적으로 zlib 알고리즘을 사용
import gzip

with open('org_data.txt', 'w') as f:
    f.write(data)
    
# gzip으로 압축
with gzip.open('compressed.txt.gz', 'wb') as f:
    f.write(data.encode('utf-8'))
    
# gzip 압축 해제
with gzip.open('compressed.txt.gz', 'rb') as f:
    org_data = f.read().decode('utf-8')

len(org_data) # 130000 bytes

zipfile

  • 여러개 파일을 zip 확장자로 합쳐서 압축할 때 사용하는 모듈
import zipfile

# 파일 합치고 압축하기
with zipfile.ZipFile('./sample/새파일.zip', 'w') as myzip:
    myzip.write('./sample/새파일1.txt')
    myzip.write('./sample/새파일2.txt')
    myzip.write('./sample/새파일3.txt')
    myzip.write('./sample/새파일4.txt')
    myzip.write('./sample/새파일5.txt')
    
# 파일 압축 해제하기
with zipfile.ZipFile('./sample/새파일.zip') as myzip:
    myzip.extractall()

tarfile

  • 여러개 파일을 tar 확장자로 합쳐서 압축할 때 사용하는 모듈
import tarfile

# 파일 합치고 압축하기
with tarfile.open('./sample/새파일.tar', 'w') as mytar:
    mytar.add('./sample/새파일1.txt')
    mytar.add('./sample/새파일2.txt')
    mytar.add('./sample/새파일3.txt')
    mytar.add('./sample/새파일4.txt')
    mytar.add('./sample/새파일5.txt')

# 파일 압축 해제하기
with tarfile.open('./sample/새파일.tar') as mytar:
    mytar.extractall()
728x90