Чтение двоичного файла с помощью python
Мне особенно сложно читать двоичный файл с 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.
Как я могу прочитать это с помощью Python? Я пробовал все, но он никогда не работал. Есть ли вероятность, что я могу использовать программу f90 в python, читая этот двоичный файл, а затем сохраните данные, которые мне нужно использовать?
Ответы
Ответ 1
Прочитайте содержимое двоичного файла следующим образом:
with open(fileName, mode='rb') as file: # b is important -> binary
fileContent = file.read()
затем "распаковать" двоичные данные с помощью struct.unpack:
Начальные байты: struct.unpack("iiiii", fileContent[:20])
Тело: игнорировать байты заголовка и конечный байт (= 24); Оставшаяся часть формирует тело, чтобы узнать, сколько байтов в теле выполняет целочисленное деление на 4; Полученный коэффициент умножается на строку 'i'
, чтобы создать правильный формат для метода распаковки:
struct.unpack("i" * ((len(fileContent) -24) // 4), fileContent[20:-4])
Конечный байт: struct.unpack("i", fileContent[-4:])
Ответ 2
В общем, я бы рекомендовал вам изучить Python struct для этого. Это стандартно с Python, и это должно быть легко перевести спецификацию вопроса в строку форматирования, подходящую для struct.unpack()
.
Обратите внимание, что если между полями "вокруг" есть "невидимое" дополнение, вам нужно будет понять это и включить его в вызов unpack()
, или вы будете читать неправильные биты.
Чтение содержимого файла для того, чтобы что-то распаковать было довольно тривиально:
import struct
data = open("from_fortran.bin", "rb").read()
(eight, N) = struct.unpack("@II", data)
Это распаковывает первые два поля, предполагая, что они начинаются с самого начала файла (без заполнения или посторонних данных), а также с учетом собственного байтового порядка (символ @
). I
в строке форматирования означает "unsigned integer, 32 bits".
Ответ 3
Вы можете использовать numpy.fromfile
, который может читать данные из текстовых и двоичных файлов. Сначала вы создадите тип данных, который представляет ваш формат файла, используя numpy.dtype
, а затем прочитайте этот тип из файла с помощью numpy.fromfile
.
Ответ 4
import pickle
f=open("filename.dat","rb")
try:
while True:
x=pickle.load(f)
print x
except EOFError:
pass
f.close()