파이썬으로 바이너리 파일을 읽는 것이 특히 어렵다는 것을 알게되었습니다. 날 도와 줄수 있습니까? 이 파일을 읽어야합니다. 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()