파일 입출력 바이너리 모드 VS 텍스트 모드 [미래 실험실 pYTHON]

안녕하세요. 언제나 휴일에 언휴예요.

강의 개요

이번 강의에서 바이너리 모드와 텍스트 모드로 파일 입출력을 해 볼 거예요.
문자열, 정수, 실수 형식 데이터인 이름, 번호, 학점을 파일에 입출력하는 실습입니다.
파일을 열 때 “wt”, “wb”, “rt”, “rb” 전달하는 인자에 따라 쓰기 모드, 읽기 모드와 바이너리 모드, 텍스트 모드를 결정합니다.
바이너리 모드의 출력에서는 변수의 값을 byte 버퍼에 pack하여 파일에 기록합니다.
바이너리 모드의 입력에서는 byte 버퍼에 읽어온 후 unpack하여 변수의 값을 설정합니다.
텍스트 모드의 출력에서는 문자열 형태로 변환하며 읽어올 때 구분할 수 있는 문자를 추가로 기록합니다.
텍스트 모드의 입력에서는 구분자 단위로 읽어온 내용을 분리합니다.
그리고 각 변수 형식에 맞게 형변환합니다.

바이너리 모드 파일 입출력

파일에 출력할 변수는 이름, 번호, 학점입니다.

name ='홍길동'
num=10
level = 3.5
그림. 버퍼에 쓰기 및 읽기
그림. 버퍼에 쓰기 및 읽기

변수의 값을 byte 버퍼로 pack

바이너리 모드 출력에서는 byte 버퍼에 pack한 후에 파일에 출력합니다.

이를 위해 name, num, level의 값을 buffer에 pack합시다.

문자열은 encode 메서드를 이용하여 bytes를 얻어옵니다.

읽어올 때를 고려하여 문자열 길이도 알아야 합니다.

ne = name.encode()
len_nb = len(ne)

byte 버퍼에 pack하거나 unpack하기 위해서 struct를 import하세요.

import struct

struct.pack 메서드에 첫 번째 인자로 어떠한 형태로 기록할 것인지 포멧 문자열을 전달합니다.

포멧타입길이
xno value 
cchar1
binteger1
?bool1
hinteger2
iinteger4
linteger4
qinteger8
ffloat4
ddouble8
표. pack의 포멧과 타입
nb = struct.pack('i',len_nb)+ne
buffer = nb+struct.pack('id',num,level)

파일에 출력

파일을 열 때는 open 함수를 이용합니다.

open 함수는 첫 번째 인자는 파일 경로명, 두 번째 인자는 모드입니다.

FILE open(파일 경로명,모드)

모드설명
r읽기 모드
w쓰기 모드
a추가모드
+읽기/쓰기
b바이너리모드
t텍스트 모드
표. open 함수의 모드

모드 중에 rwa 중에 하나는 반드시 선택해야 합니다.

bytes를 기록할 때는 wrtie 함수를 호출합니다.

파일을 닫을 때는 close 함수를 호출합니다.

file = open("data.txt","wb")
file.write(buffer)
file.close()

파일에서 읽기

읽기 모드로 열고 read 함수로 읽어옵니다.

file2 = open("data.txt","rb")
buffer2 = file2.read()
file2.close()

byte 버퍼에서 변수로 unpack하기

byte 버퍼에 있는 내용을 unpack할 때 struct.unpack을 호출합니다.

첫 번째 인자는 포멧 문자열이며 두 번째 인자는 버퍼에서 읽어올 bytes를 지정합니다.

지정할 때는 [시작:끝]을 사용합니다.

 

name2=""
num2=0
level2=0.

pos = 0
len_nb2, = struct.unpack('i',buffer2[pos:4])
pos+=4
ne2 = buffer2[pos:(pos+len_nb2)]
pos+=len_nb2
name2 = ne2.decode()
num2,level2 = struct.unpack('id',buffer2[pos:])

바이너리 입출력 전체 코드

#바이너리 모드 파일 입출력

name ='홍길동'
num=10
level = 3.5

ne = name.encode()
len_nb = len(ne)

import struct
nb = struct.pack('i',len_nb)+ne
buffer = nb+struct.pack('id',num,level)

file = open("data.txt","wb")
file.write(buffer)
file.close()

file2 = open("data.txt","rb")
buffer2 = file2.read()
file2.close()


name2=""
num2=0
level2=0.

pos = 0
len_nb2, = struct.unpack('i',buffer2[pos:4])
pos+=4
ne2 = buffer2[pos:(pos+len_nb2)]
pos+=len_nb2
name2 = ne2.decode()
num2,level2 = struct.unpack('id',buffer2[pos:])

print("이름:",name2," 번호:",num2," 학점:",level2)

텍스트 모드 파일 입출력

텍스트 모드 출력은 문자열로 출력합니다.

파일에서 읽어올 때를 어떠한 문자를 기준으로 구분할 것인지 결정하고 함께 출력합니다.

읽어올 때는 전체 내용을 구분하는 문자로 구분하여 읽어옵니다.

다른 형식을 문자열로 변환할 때는 str 함수를 사용합니다.

문자열 str(값)

nstr = str(num)

문자열에 기록한 특정 형식 값을 해당 형식으로 변환할 때는 강제 형변환을 사용하세요.

변수 = 형변환 타입(문자열)

num = int(nstr)

#텍스트 모드 파일 입출력

name ='홍길동'
num=10
level = 3.5

ft = open("data2.txt","wt")
ft.write(name+"\n")
ft.write(str(num)+"\n")
ft.write(str(level)+"\n")
ft.close()

ft2 = open("data2.txt","rt")
datas = ft2.read().splitlines()
ft2.close()

name2= datas[0]
num2= int(datas[1])
level2=float(datas[2])

print("이름:",name2," 번호:",num2," 학점:",level2)

파일의 내용 비교

그림. 바이너리 파일과 텍스트 파일 내용 비교
그림. 바이너리 파일과 텍스트 파일 내용 비교