Python 바 이 너 리 배열 데 이 터 를 읽 고 쓰 는 방법
파 이 썬 모듈 에 바 이 너 리 배열 의 구조 화 된 데 이 터 를 읽 고 싶 습 니 다.
해결 방안
struct
모듈 로 바 이 너 리 데 이 터 를 처리 할 수 있 습 니 다.다음은 예제 코드 입 니 다.Python 모듈 목록 을 바 이 너 리 파일 에 기록 하고struct
각 모듈 을 하나의 구조 체 로 인 코딩 합 니 다.
from struct import Struct
def write_records(records, format, f):
'''
Write a sequence of tuples to a binary file of structures.
'''
record_struct = Struct(format)
for r in records:
f.write(record_struct.pack(*r))
# Example
if __name__ == '__main__':
records = [ (1, 2.3, 4.5),
(6, 7.8, 9.0),
(12, 13.4, 56.7) ]
with open('data.b', 'wb') as f:
write_records(records, '<idd', f)
이 파일 을 읽 고 원 그룹 목록 으로 돌아 가 는 방법 은 여러 가지 가 있 습 니 다.우선,블록 형식 으로 파일 을 추가 로 읽 으 려 면 이렇게 할 수 있 습 니 다.
from struct import Struct
def read_records(format, f):
record_struct = Struct(format)
chunks = iter(lambda: f.read(record_struct.size), b'')
return (record_struct.unpack(chunk) for chunk in chunks)
# Example
if __name__ == '__main__':
with open('data.b','rb') as f:
for rec in read_records('<idd', f):
# Process rec
...
모든 파일 을 한 바이트 문자열 에 한꺼번에 읽 고 나 서 조각 을 나 누 어 분석 하고 싶다 면.그러면 너 는 이렇게 할 수 있다.
from struct import Struct
def unpack_records(format, data):
record_struct = Struct(format)
return (record_struct.unpack_from(data, offset)
for offset in range(0, len(data), record_struct.size))
# Example
if __name__ == '__main__':
with open('data.b', 'rb') as f:
data = f.read()
for rec in unpack_records('<idd', data):
# Process rec
...
두 가지 상황 에서 결 과 는 이 파일 을 만 드 는 원본 그룹 으로 되 돌아 갈 수 있 는 교체 가능 한 대상 입 니 다.토론 하 다.
바 이 너 리 데 이 터 를 인 코딩 하고 디 코딩 해 야 하 는 프로그램 에 서 는 보통
struct
모듈 을 사용 합 니 다.새로운 구조 체 를 설명 하기 위해 서 는 이렇게Struct
인 스 턴 스 를 만 들 면 됩 니 다.
# Little endian 32-bit integer, two double precision floats
record_struct = Struct('<idd')
구조 체 는 보통 구조 코드 값 i,d,f 등[참고파 이 썬 문서]을 사용한다.이 코드 들 은 32 비트 정수,64 비트 부동 소수점,32 비트 부동 소수점 등 특정한 바 이 너 리 데이터 형식 을 대표 한다.첫 번 째 문자<바이트 순 서 를 지 정 했 습 니 다.이 예 에서 그것 은'낮은 위치 가 앞 에 있다'는 것 을 나타 낸다.이 문 자 를>로 변경 하면 상위 가 앞 에 있 거나!네트워크 바이트 순 서 를 나타 낸다.발생 하 는
Struct
인 스 턴 스 는 해당 유형의 구 조 를 조작 하 는 속성 과 방법 이 많다.size
속성 은 구조의 바이트 수 를 포함 하 는데 이것 은 I/O 작업 에 매우 유용 하 다.pack()
와unpack()
방법 은 데 이 터 를 포장 하고 해제 하 는 데 사용 된다.예 를 들 면:
>>> from struct import Struct
>>> record_struct = Struct('<idd')
>>> record_struct.size
20
>>> record_struct.pack(1, 2.0, 3.0)
b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x08@'
>>> record_struct.unpack(_)
(1, 2.0, 3.0)
>>>
가끔 은pack()
와unpack()
조작 이 모듈 급 함수 로 호출 되 는 것 을 볼 수 있 습 니 다.아래 와 같 습 니 다.
>>> import struct
>>> struct.pack('<idd', 1, 2.0, 3.0)
b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x08@'
>>> struct.unpack('<idd', _)
(1, 2.0, 3.0)
>>>
이렇게 하면 일 을 할 수 있 지만 인 스 턴 스 방법 만큼 우아 하지 않 은 것 같 습 니 다.특히 코드 에 같은 구조 가 여러 곳 에 나 타 났 을 때.하나의Struct
인 스 턴 스 를 만 들 면 형식 코드 는 한 번 만 지정 되 고 모든 작업 이 집중 적 으로 처 리 됩 니 다.이렇게 되면 코드 유지 보수 가 더욱 간단 해진 다.바 이 너 리 구 조 를 읽 는 코드 는 매우 재 미 있 고 아름 다운 프로 그래 밍 기술 을 사용 해 야 한다.함수
read_records
에서iter()
는 고정 크기 의 데이터 블록 을 되 돌려 주 는 교체 기 를 만 드 는 데 사 용 됩 니 다.이 교체 기 는 사용자 가 제공 하 는 호출 가능 한 대상(예 를 들 어lambda: f.read(record_struct.size)
을 계속 호출 하여 특수 한 값(예 를 들 어 b')을 되 돌려 줄 때 까지 교체 가 중단 된다.예 를 들 면:
>>> f = open('data.b', 'rb')
>>> chunks = iter(lambda: f.read(20), b'')
>>> chunks
<callable_iterator object at 0x10069e6d0>
>>> for chk in chunks:
... print(chk)
...
b'\x01\x00\x00\x00ffffff\x02@\x00\x00\x00\x00\x00\x00\x12@'
b'\x06\x00\x00\x00333333\x1f@\x00\x00\x00\x00\x00\x00"@'
b'\x0c\x00\x00\x00\xcd\xcc\xcc\xcc\xcc\xcc*@\x9a\x99\x99\x99\x99YL@'
>>>
보시 다시 피 교체 가능 한 대상 을 만 드 는 이 유 는 생 성기 유도 로 기록 을 만 들 수 있 기 때 문 입 니 다.만약 당신 이 이런 기술 을 사용 하지 않 는 다 면 코드 는 아래 와 같이 될 수 있 습 니 다.
def read_records(format, f):
record_struct = Struct(format)
while True:
chk = f.read(record_struct.size)
if chk == b'':
break
yield record_struct.unpack(chk)
함수 unpack_records()
에서 다른 방법unpack_from()
을 사용 했다.unpack_from()은 대형 바 이 너 리 배열 에서 바 이 너 리 데 이 터 를 추출 하 는 데 매우 유용 합 니 다.임시 대상 이 생기 거나 메모리 복사 작업 을 하지 않 기 때 문 입 니 다.바이트 문자열(또는 배열)과 바이트 오프셋 만 주면 그 위치 에서 데 이 터 를 직접 풀 수 있 습 니 다.만약 당신 이
unpack()
을 사용 하여 대체unpack_from()
한다 면,당신 은 코드 를 수정 하여 대량의 작은 절편 을 구성 하고 오프셋 을 계산 해 야 합 니 다.예 를 들 면:
def unpack_records(format, data):
record_struct = Struct(format)
return (record_struct.unpack(data[offset:offset + record_struct.size])
for offset in range(0, len(data), record_struct.size))
이 방안 은 코드 가 복잡 해 보 이 는 것 외 에 도 많은 추가 작업 을 해 야 한다.왜냐하면 그것 은 대량의 오프셋 계산,데이터 복제 와 구조 가 작은 절편 대상 을 실 행 했 기 때문이다.읽 은 대형 바이트 문자열 에서 대량의 구조 체 를 풀 려 고 한다 면unpack_from()
더 잘 할 것 입 니 다.패 키 지 를 풀 때
collections
모듈 의 이름 을 가 진 메타 그룹 대상 은 사용 하고 싶 은 것 일 수도 있 습 니 다.원 그룹 으로 돌아 가 속성 이름 을 설정 할 수 있 습 니 다.예 를 들 면:
from collections import namedtuple
Record = namedtuple('Record', ['kind','x','y'])
with open('data.p', 'rb') as f:
records = (Record(*r) for r in read_records('<idd', f))
for r in records:
print(r.kind, r.x, r.y)
프로그램 이 바 이 너 리 데 이 터 를 많이 처리 해 야 한다 면numpy
모듈 을 사용 하 는 것 이 좋 습 니 다.예 를 들 어 원 그룹 목록 이 아 닌 구조 화 된 배열 로 바 이 너 리 데 이 터 를 읽 을 수 있 습 니 다.아래 처럼:
>>> import numpy as np
>>> f = open('data.b', 'rb')
>>> records = np.fromfile(f, dtype='<i,<d,<d')
>>> records
array([(1, 2.3, 4.5), (6, 7.8, 9.0), (12, 13.4, 56.7)],
dtype=[('f0', '<i4'), ('f1', '<f8'), ('f2', '<f8')])
>>> records[0]
(1, 2.3, 4.5)
>>> records[1]
(6, 7.8, 9.0)
>>>
마지막 으로 알려 진 파일 형식(예 를 들 어 그림 형식,그래 픽 파일,HDF 5 등)에서 바 이 너 리 데 이 터 를 읽 을 필요 가 있 을 때 Python 이 기 존 모듈 을 제 공 했 는 지 확인 하 십시오.어 쩔 수 없 이 바퀴 를 다시 만 들 필요 가 없 기 때문이다.이상 은 파 이 썬 이 바 이 너 리 배열 데 이 터 를 어떻게 읽 고 쓰 는 지 에 대한 상세 한 내용 입 니 다.파 이 썬 이 바 이 너 리 배열 데 이 터 를 읽 고 쓰 는 데 관 한 자 료 는 다른 관련 글 에 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python의 None과 NULL의 차이점 상세 정보그래서 대상 = 속성 + 방법 (사실 방법도 하나의 속성, 데이터 속성과 구별되는 호출 가능한 속성 같은 속성과 방법을 가진 대상을 클래스, 즉 Classl로 분류할 수 있다.클래스는 하나의 청사진과 같아서 하나의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.