파일을 다루기 위한 객체를 생성하기 위해서는 내장 함수인 open() 함수를 사용합니다.

open() 함수를 호출 할 때 " 파일 이름 "과 " 모드 "를 인자로 전달하며, 결과 값으로는 파일 객체를 반환합니다.


파일객체 = open( file, mode )

1) file     : 파일 경로

파일 경로가 /로 시작할 경우, C 또는 D 드라이브의 경로를 시작으로 하고, ( 프로젝트 폴더 위치 기준 드라이브 )

파일 경로에 /가 없을 경우, 프로젝트 폴더의 내부 경로를 시작으로 파일 경로를 인식합니다.



2) mode    : 파일 객체를 통해 수행 할 수 있는 행위를 의미하며, 다음 문자열의 조합으로 사용합니다.

r    -> 읽기 ( default )

w   -> 쓰기 ( 덮어쓰기 )

a    -> 쓰기 ( 이어쓰기 )

+    -> 읽기 + 쓰기

--------------------------------------------

t     -> text 모드 ( default )

b    -> binary 모드





파일 쓰기

# text 모드
f1 = open('/Users/test.txt', 'w', encoding='utf-8') # C:\Users
f1.write('Hello !\nPython')

f1.close()


# binary 모드
file2 = open('text2.txt', 'wb') # C:\Users\samsung\PycharmProjects\test
file2.write(bytes('Hello !\nPython', encoding='utf-8'))

file2.close()

파일 객체를 얻기 위해 open() 함수를 호출할 때, 모드에 w를 작성하면 " 쓰기 " 모드가 되며, b를 작성하면 " binary "라는 의미가 됩니다.

파일을 쓰는 방법은 open() 함수로 얻은 파일 객체에 write() 메서드를 사용하면 됩니다.





파일 읽기

# text 읽기
file1 = open('/Users/test.txt', 'r', encoding='utf-8')
text = file1.read()
print(text)
file1.close()


# binary 파일( 이미지 파일 ) copy하기
file2 = open('example_img.png', 'rb')
data = file2.read()
print(type(data))        # <class 'bytes'>

file2.close()

file3 = open('example_img2.png', 'wb')
file3.write(data)
file3.close()

파일을 읽는 방법도 간단합니다.

open() 함수를 호출할 때, 모드에 r을 작성하면 " 읽기 "모드가 되고, read() 메서드를 호출하면 파일 읽기가 수행됩니다.


그리고 binary를 읽기 위해서 이미지 파일을 하나 준비해주세요.

이미지 파일은 현재 디렉터리 경로에 놓습니다.

두 번째 코드는 example_img.png 파일을 binary로 읽어서 binary로 example_img2.png 파일로 복사하는 코드입니다.





줄 단위로 읽기

텍스트가 여러 줄로 있을 때, 줄 단위로 읽는 방법에 대해 알아보겠습니다.

줄 단위로 읽는 방법은 무한 루프를 돌면서 readline() 메서드를 호출하면 됩니다.

# readline() - 줄 단위로 읽어서 반환
file1 = open('/Users/test.txt', 'r', encoding='utf-8')
while True:
line = file1.readline()
if line == '':
file1.close()
break
print(line, end='')


# readlines() - 줄 단위로 모두 읽어서 리스트로 반환
file2 = open('/Users/test.txt', 'r', encoding='utf-8')
lines = file2.readlines()

file2.close()
print(lines) # ['Hello !\n', 'Python'] => 리스트





with ~ as ~   :  자동으로 자원 정리

지금까지의 코드를 살펴보면 항상 마지막 close() 메서드를 호출했던 것을 확인할 수 있습니다.

이는 파일 입출력에 필요한 자원들을 정리하는 메서드이므로, 자원 낭비를 막으려면 꼭 호출해줘야 합니다.


그런데 편리하게도 with ~ as ~ 구문을 사용하면 자동으로 자원 정리를 할 수 있도록 할 수 있습니다.

이는 java에서 try ~ catch ~ resource 구문과 같습니다.

with open('/Users/test.txt', 'r', encoding='utf-8') as file1:
text = file1.read()
print(text)
print(file1.closed) # True => file1 객체는 이미 닫혀있다.





codecs  : encoding 문제 해결

브라우저에서 서버로 넘어온 문자열을 파일로 저장할 때, encoding 문제가 발생할 수 있습니다.

저는 브라우저로부터 받은 한글 문자열을 파일로 저장하기 위해서, 에디터의 인코딩도 바꿔보고 별 짓을 다해봤는데, 결국 codecswith ~ as 를 사용하여 해결했습니다.

import codecs
def client_input_save(input_data):
input_data = str(input_data)

file_path = 'test.txt'
with codecs.open(file_path, 'w', encoding='utf-8') as file:
file.write(input_data)




이상으로 Python에서 파일 입출력을 하는 방법에 대해 알아보았습니다.

여기까지 Python의 기본 문법을 마치고, 다음 글에서부터는 유명한 라이브러리를 이용하여 크롤링하는 방법에 대해 알아보겠습니다.