모든 문자열에 'b'를 포함하면 파일이 이진 모드로 열립니다. 이 경우 문자열 대신 바이트를 읽고 씁니다.
이진 시가 없기 때문에 0에서 255까지의 256바이트 값만 생성합니다.
>>> bdata = bytes(range(0, 256))
>>> len(bdata)
256
이진 모드에서 쓰기 위한 파일을 열고 모든 데이터를 한 번에 씁니다.
>>> fout = open('bfile', 'wb')
>>> fout.write(bdata)
256
>>> fout.close()
다시 쓰기()는 기록된 바이트 수를 반환합니다. 텍스트와 마찬가지로 이진 데이터를 청크로 쓸 수 있습니다.
>>> fout = open('bfile', 'wb')
>>> size = len(bdata)
>>> offset = 0
>>> chunk = 100
>>> while True:
... if offset > size:
... break
... fout.write(bdata[offset:offset+chunk]) ... offset += chunk
...
100
100
56
>>> fout.close()
읽기()를 사용하여 이진 파일 읽기
이 방법은 간단합니다. 'rb'로 열기만 하면 됩니다.
>>> fin = open('bfile', 'rb')
>>> bdata = fin.read()
>>> len(bdata)
256
>>> fin.close()
Close Files Automatically by Using with
열어본 파일을 닫지 않은 경우 더 이상 참조되지 않은 후 파이썬에 의해 닫힙니다. 즉, 함수 내에서 파일을 열고 명시적으로 닫지 않으면 함수가 종료될 때 파일이 자동으로 닫힙니다. 그러나 장기간 실행되는 기능이나 프로그램의 기본 섹션에서 파일을 열었을 수 있습니다. 나머지 쓰기를 강제로 완료하려면 파일을 닫아야 합니다.
파이썬에는 열린 파일과 같은 것들을 정리할 수 있는 컨텍스트 관리자가 있습니다. 식을 변수로 사용하여 양식을 사용할 수식입니다.
>>> with open('relativity', 'wt') as fout: ... fout.write(poem)
...
바로 그거예요. 컨텍스트 관리자 아래의 코드 블록(이 경우, 한 줄)이 완료된 후(일반적으로 또는 상향된 예외에 의해) 파일은 자동으로 닫힙니다.
탐색()으로 위치 변경
읽고 쓸 때 파이썬은 파일 내의 위치를 추적합니다. tell() 함수는 파일 시작 부분의 현재 오프셋(바이트)을 반환합니다. seek() 기능을 사용하여 파일의 다른 바이트 오프셋으로 이동할 수 있습니다. 즉, 마지막 바이트를 읽기 위해 파일의 모든 바이트를 읽을 필요는 없습니다. 마지막 바이트까지 찾고 1바이트만 읽을 수 있습니다.
이 예에서는 앞에서 작성한 256바이트 이진 파일 'bfile'을 사용합니다.
>>> fin = open('bfile', 'rb')
>>> fin.tell()
0
파일이 끝나기 전에 seek()를 1바이트까지 사용합니다.
>>> fin.seek(255)
255
파일 끝까지 읽기:
>>> bdata = fin.read()
>>> len(bdata)
1
>>> bdata[0]
255
seek()는 현재 오프셋도 반환합니다.
두 번째 인수를 사용하여 seek()를 호출할 수 있습니다. seek(오프셋, 오리진):
• 오리진이 0(기본값)이면 처음부터 오프셋 바이트로 이동합니다.
• 발신지가 1인 경우 현재 위치에서 오프셋 바이트로 이동
• 원본이 2인 경우, 끝 부분에 상대적인 오프셋 바이트로 이동합니다.
다음 값은 표준 OS 모듈에도 정의되어 있습니다.
- >>> import os >>> os.SEEK_SET 0
>>> os.SEEK_CUR 1
>>> os.SEEK_END - 2
마지막 바이트는 다른 방식으로 읽을 수 있었습니다.
- >>> fin = open('bfile', 'rb')
파일 종료 전 1바이트:
>>> fin.seek(-1, 2)
255
>>> fin.tell()
255
파일 끝까지 읽기:
>>> bdata = fin.read()
>>> len(bdata)
1
>>> bdata[0]
255
구직 활동을 위해 tell을 부를 필요는 없다. 나는 단지 그들이 둘 다 같은 오프셋을 보고한다는 것을 보여주고 싶었다.
다음은 파일의 현재 위치에서 찾는 예제입니다.
>>> fin = open('bfile', 'rb')
이 다음 예는 파일이 끝나기 전에 2바이트가 됩니다.
>>> fin.seek(254, 0)
254
>>> fin.tell()
254
이제 1바이트 앞으로 이동합니다.
>>> fin.seek(1, 1)
255
>>> fin.tell()
255
마지막으로 파일 끝까지 읽습니다.
>>> bdata = fin.read()
>>> len(bdata)
1
>>> bdata[0]
255
이러한 함수는 이진 파일에 가장 유용합니다. 텍스트 파일과 함께 사용할 수 있지만, 파일이 ASCII(문자당 1바이트)가 아니면 오프셋을 계산하는 데 어려움이 있을 수 있습니다. 이는 텍스트 인코딩에 따라 달라지며 가장 널리 사용되는 인코딩(UTF-8)은 문자당 바이트 수를 다르게 사용합니다.
구조화된 텍스트 파일
단순 텍스트 파일의 경우 구성 수준은 줄뿐입니다. 때때로, 여러분은 그것보다 더 많은 구조를 원합니다. 프로그램에서 나중에 사용할 수 있도록 데이터를 저장하거나 다른 프로그램으로 데이터를 보낼 수 있습니다.
형식은 여러 가지가 있으며, 다음과 같이 구분할 수 있습니다.
• 탭('\t', 쉼표(',), 세로 막대 등의 구분 기호 또는 구분 기호
('|') CSV(쉼표로 구분된 값) 형식의 예입니다.
• 태그 주위에 '' 및 '''가 있습니다. 예를 들어 XML 및 HTML을 들 수 있습니다.
• 구두점. 예를 들어 자바스크립트 객체 표기법(JSON)이 있습니다.
• 들여쓰기. 예를 들어 YAML이 있습니다. 사용하는 출처에 따라 "YAML은 마크업 언어가 아닙니다. 직접 연구해야 합니다.
• 프로그램 구성 파일과 같은 기타.
이러한 각각의 구조화된 파일 형식은 하나 이상의 파이썬 모듈로 읽고 쓸 수 있다.
CSV
구분된 파일은 종종 스프레드시트 및 데이터베이스의 교환 형식으로 사용됩니다. CSV 파일을 한 번에 한 줄씩 수동으로 읽고 각 줄을 쉼표 구분 기호로 필드로 분할한 다음 목록 및 사전 양자와 같은 데이터 구조에 결과를 추가할 수 있습니다. 그러나 표준 csv 모듈을 사용하는 것이 좋습니다. 이러한 파일을 구문 분석하는 작업은 생각보다 복잡해질 수 있습니다.
• 쉼표 외에 다른 구분 기호를 사용하는 경우도 있습니다. '|' 및 '\t'(탭)가 일반적입니다.
• 일부는 이스케이프 시퀀스가 있습니다. 구분 기호 문자가 필드 내에서 발생할 수 있는 경우 전체 필드에는 따옴표 문자가 있거나 일부 이스케이프 문자가 앞에 있을 수 있습니다.
• 파일의 줄 끝 문자가 다릅니다. Unix는 '\n', Microsoft는 '\r \n', Apple은 '\r'을 사용했지만 지금은 '\n'을 사용합니다.
• 첫 줄에 열 이름이 있을 수 있습니다.
먼저, 각 행에 열 목록이 포함된 행 목록을 읽고 쓰는 방법에 대해 알아보겠습니다.
- >>> import csv >>> villains = [
... ['Ernst', 'Blofeld'],
... ]
>>> with open('villains', 'wt') as fout: # a context manager ... csvout = csv.writer(fout)
... csvout.writerows(villains)
그러면 다음과 같은 행으로 파일 악당이 생성됩니다.
Doctor,No
Rosa,Klebb
Mister,Big
Auric,Goldfinger
Ernst,Blofeld
이제 다시 읽어보겠습니다.
>>> import csv
>>> with open('villains', 'rt') as fin: # context manager
- ... cin = csv.reader(fin)
- ... villains = [row for row in cin] # This uses a list comprehension ...
>>> print(villains)
[['Doctor', 'No'], ['Rosa', 'Klebb'], ['Mister', 'Big'],
['Auric', 'Goldfinger'], ['Ernst', 'Blofeld']]
잠시 목록 이해에 대해 생각해 보십시오. 우리는 리더() 함수에 의해 만들어진 구조를 이용했다. cin 객체에 행을 생성해 루프를 위해 a에서 추출할 수 있습니다.
기본 선택사항과 함께 독서자() 및 작성기()를 사용하여 열은 쉼표로 구분되고 행은 행 피드로 구분됩니다.
데이터는 목록 목록이 아닌 사전 목록일 수 있습니다. 이번에는 새 DictReader() 함수를 사용하여 다음과 같은 열 이름을 지정하여 악당 파일을 다시 읽어보겠습니다.
- >>> import csv
>>> with open('villains', 'rt') as fin:
새로운 DictWriter() 함수를 사용하여 CSV 파일을 다시 쓰겠습니다. 또한 CSV 파일에 열 이름의 초기 줄을 쓰기 위해 쓰기 헤더()를 호출합니다.
import csv villains = [
{'first': 'Doctor', 'last': 'No'},
{'first': 'Rosa', 'last': 'Klebb'},
{'first': 'Mister', 'last': 'Big'},
{'first': 'Auric', 'last': 'Goldfinger'},
{'first': 'Ernst', 'last': 'Blofeld'},
]
with open('villains', 'wt') as fout:
cout = csv.DictWriter(fout, ['first', 'last'])
cout.writeheader()
cout.writerows(villains)
그러면 머리글 줄이 있는 악당 파일이 생성됩니다.
first,last
Doctor,No
Rosa,Klebb
Mister,Big
Auric,Goldfinger
Ernst,Blofeld
이제 다시 읽어보겠습니다. DictReader() 호출에서 필드 이름 인수를 생략하여 파일의 첫 줄(첫 번째, 마지막)에 있는 값을 열 레이블 및 일치하는 사전 키로 사용하도록 지시합니다.
>>> import csv
>>> with open('villains', 'rt') as fin:
- ... cin = csv.DictReader(fin)
- ... villains = [row for row in cin] ...>>> print(villains)[{'last': 'No', 'first': 'Doctor'}, {'last': 'Klebb', 'first': 'Rosa'}, {'last': 'Big', 'first': 'Mister'}, {'last': 'Goldfinger', 'first': 'Auric'}, {'last': 'Blofeld', 'first': 'Ernst'}]