Чтение двоичного файла с помощью 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, читая этот двоичный файл, а затем сохранить данные, которые мне нужно использовать?
4 ответа:
прочитайте содержимое двоичного файла следующим образом:
with open(fileName, mode='rb') as file: # b is important -> binary fileContent = file.read()
затем "распаковать" двоичные данные с помощью структура.распакуйте:
старт байт:
struct.unpack("iiiii", fileContent[:20])
тело: игнорировать заголовочные байты и конечный байт (= 24); оставшаяся часть образует тело, чтобы узнать количество байтов в теле сделать целочисленное деление на 4; полученный фактор умножается на строку
'i'
создать правильный формат для распаковки метод:struct.unpack("i" * ((len(fileContent) -24) // 4), fileContent[20:-4])
конечный байт:
struct.unpack("i", fileContent[-4:])
В общем, я бы рекомендовал вам изучить использование Python struct модуль для этого. Это стандартно для Python, и должно быть легко перевести спецификацию вашего вопроса в строку форматирования, подходящую для
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
.