[python] 파이썬으로 바이너리 파일 읽기

파이썬으로 바이너리 파일을 읽는 것이 특히 어렵다는 것을 알게되었습니다. 날 도와 줄수 있습니까? 이 파일을 읽어야합니다. Fortran 90에서는 쉽게 읽을 수 있습니다.

int*4 n_particles, n_groups
real*4 group_id(n_particles)
read (*) n_particles, n_groups
read (*) (group_id(j),j=1,n_particles)

세부적으로 파일 형식은 다음과 같습니다.

Bytes 1-4 -- The integer 8.
Bytes 5-8 -- The number of particles, N.
Bytes 9-12 -- The number of groups.
Bytes 13-16 -- The integer 8.
Bytes 17-20 -- The integer 4*N.
Next many bytes -- The group ID numbers for all the particles.
Last 4 bytes -- The integer 4*N. 

파이썬으로 어떻게 읽을 수 있습니까? 나는 모든 것을 시도했지만 결코 효과가 없었습니다. 파이썬에서 f90 프로그램을 사용하여이 바이너리 파일을 읽은 다음 필요한 데이터를 저장할 가능성이 있습니까?



답변

이진 파일 내용을 다음과 같이 읽으십시오.

with open(fileName, mode='rb') as file: # b is important -> binary
    fileContent = file.read()

그런 다음 struct.unpack을 사용하여 이진 데이터를 “압축 해제”합니다 .

시작 바이트 : struct.unpack("iiiii", fileContent[:20])

본문 : 표제 바이트와 후행 바이트 무시 (= 24); 나머지 부분은 본문을 형성하고 본문의 바이트 수를 알기 위해 정수를 4로 나눕니다. 얻은 몫에 문자열 'i'을 곱하여 unpack 메서드에 대한 올바른 형식을 만듭니다.

struct.unpack("i" * ((len(fileContent) -24) // 4), fileContent[20:-4])

끝 바이트 : struct.unpack("i", fileContent[-4:])


답변

일반적으로 이를 위해 Python의 struct 모듈을 사용하는 것이 좋습니다 . Python의 표준이며 질문의 사양을 .NET에 적합한 형식 지정 문자열로 쉽게 변환 할 수 있어야합니다 struct.unpack().

필드 사이 / 주위에 “보이지 않는”패딩이있는 경우이를 파악하여 unpack()호출에 포함해야합니다 . 그렇지 않으면 잘못된 비트를 읽게됩니다.

압축을 풀기 위해 파일의 내용을 읽는 것은 매우 간단합니다.

import struct

data = open("from_fortran.bin", "rb").read()

(eight, N) = struct.unpack("@II", data)

이렇게하면 파일의 맨 처음 (패딩 또는 관련없는 데이터 없음)에서 시작하고 기본 바이트 순서 ( @기호)를 가정한다고 가정하고 처음 두 필드의 압축을 풉니 다 . I형식화 문자열 의 s는 “부호없는 정수, 32 비트”를 의미합니다.


답변

numpy.fromfile텍스트와 바이너리 파일 모두에서 데이터를 읽을 수있는를 사용할 수 있습니다. 먼저를 사용하여 파일 형식을 나타내는 데이터 유형을 생성 한 numpy.dtype다음 numpy.fromfile.


답변

바이너리 파일을 bytes객체로 읽으려면 :

from pathlib import Path
data = Path('/path/to/file').read_bytes()  # Python 3.5+

int데이터의 0-3 바이트에서 생성하려면 :

i = int.from_bytes(data[:4], byteorder='little', signed=False)

int데이터에서 여러 s의 압축을 풀려면 :

import struct
ints = struct.unpack('iiii', data[:16])

답변

나도 바이너리 파일을 읽고 쓸 때 파이썬이 부족하다는 것을 알았으므로 작은 모듈 (Python 3.6 이상용)을 작성했습니다.

binaryfile 을 사용하면 다음과 같이 할 수 있습니다 (Fortran을 모르기 때문에 추측합니다).

import binaryfile

def particle_file(f):
    f.array('group_ids')  # Declare group_ids to be an array (so we can use it in a loop)
    f.skip(4)  # Bytes 1-4
    num_particles = f.count('num_particles', 'group_ids', 4)  # Bytes 5-8
    f.int('num_groups', 4)  # Bytes 9-12
    f.skip(8)  # Bytes 13-20
    for i in range(num_particles):
        f.struct('group_ids', '>f')  # 4 bytes x num_particles
    f.skip(4)

with open('myfile.bin', 'rb') as fh:
    result = binaryfile.read(fh, particle_file)
print(result)

다음과 같은 출력이 생성됩니다.

{
    'group_ids': [(1.0,), (0.0,), (2.0,), (0.0,), (1.0,)],
    '__skipped': [b'\x00\x00\x00\x08', b'\x00\x00\x00\x08\x00\x00\x00\x14', b'\x00\x00\x00\x14'],
    'num_particles': 5,
    'num_groups': 3
}

Fortran이 추가하는 추가 데이터를 건너 뛰기 위해 skip ()을 사용했지만 대신 Fortran 레코드를 올바르게 처리하는 유틸리티를 추가 할 수 있습니다. 그렇게한다면 풀 리퀘스트를 환영합니다.


답변

import pickle
f=open("filename.dat","rb")
try:
    while True:
        x=pickle.load(f)
        print x
except EOFError:
    pass
f.close()


답변