Tip! 추가 내용
open()
함수를 이용해서 파일 객체를 만들고, read()
메소드를 이용해서 파일의 전체 내용을 한 번에 읽어오는 것read()
를 이용해서 파일의 전체 내용을 읽어와 하나의 문자열로 사용readlines()
를 이용하면 파일의 전체 내용을 읽어와서 라인 단위로 잘라 문자열의 리스트로 만들 수 있음readline()
을 이용해서 파일의 내용을 한 줄씩 읽어와서 처리readline()
이 가장 많이 쓰이며, 아예 텍스트 파일을 연 파일 객체는 문자열의 제너레이터처럼 동작하기 때문에 for ... in
구문으로 한줄씩 데이터를 읽어서 사용Tip! 파싱(Parsing)이란?
- 문서나 HTML 등 어떤 큰 자료에서 내가 원하는 정보만 가공하고 추출해서 원할 때 불러올 수 있게 하는 것
- 특정 패턴이나 순서로 추출해서 정보로 가공할 수 있고 XML, DOM, SAX, JSON 등과 같은 파싱 기법이 있음
- 파싱을 수행하는 프로그램은 파서(Parser)라고 함
split()
으로 나눠서 써야겠지만, split()
이라는 동작 자체가 일단 잘라낼 문자열을 메모리에 올린 다음, 한꺼번에 잘라서 리스트로 만드는 방식으로 처리되기 때문에 실제 문자열의 크기의 두 배 이상의 메모리를 요구하게 됨def read_strem(filename, sep=","):
## filename : 읽을 파일
## sep : 구분자
buffer = bytearray()
chunk_size = 1024 # 한 번에 1024바이트씩 읽어온다.
token = sep.encode()
with open(filename, 'rb') as f: ## 파일을 이진 파일로 읽어온다.
while True:
data = f.read(chunk_size)
if not data: ## 파일에서 더이상 읽을 내용이 없으면 루프 종료
break
buffer.extend(data)
## 버퍼내에서 구분자까지 자르는 작업을 반복
while True:
i = buffer.find(token)
if i < 0 : ## 구분자가 발견되지 않으면 한 번 더 읽어온다.
break
found = buffer[:i].decode()
yield found
## 구분자앞까지 자른 내용을 내놓은 후에는 버퍼의 앞쪽을 정리한다.
buffer[:i+len(token)] = []
## 파일에서 읽는 내용을 모두 처리했다. 버퍼에 남은 내용이 있으면 내놓는다.
if buffer:
yield buffer.decode()
for 문
에서 사용할 수 있고, 만약 앞 1000개까지만 사용하려면 다음과 같이 쓸 수 있음## 파일이름이 'verybigfile.txt'라 할 때,
g = read_stream('verybigfile.txt')
for (i, w) in enumerate(g):
if not i < 1000:
break
print(w)
Objective-C
나 Swift
에 어울릴 것 같은 방법인데, "필요할 때마다 꺼내 쓰는" 제너레이터가 아니라 튀어나오는 데이터를 처리할 핸들러를 넘겨주고 함수 내에서 다 처리해버리는 방법None
이나 False
로 평가되는 값을 리턴하면 계속하고, 그렇지 않으면 더 이상 실행하지 않도록 하면 됨def process_word(word, idx):
if idx < 10:
print(word)
return
return True
def split_file(filename, handler, sep=","):
buffer = bytearray()
chunk_size = 1024
token = sep.encode()
idx = 0
with open(filename, 'rb') as f:
while True:
data = f.read(chunk_size)
if not data:
break
buffer.extend(data)
while True:
i = buffer.find(token)
if i < 0:
break
found = buffer[:i].decode()
r = handler(found, idx)
if r:
return
buffer[:i+len(token)], idx = [], idx+1
if buffer:
handler(buffer.decode(), idx)
## 10개 데이터만 출력하고 끝낸다.
split_file('varybidfile.txt', process_word)