Чтение двоичного файла с помощью Python - PullRequest
78 голосов
/ 03 января 2012

Мне особенно трудно читать двоичный файл с помощью Python. Можешь дать мне руку? Мне нужно прочитать этот файл, который в Фортране 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, прочитать этот двоичный файл и затем сохранить данные, которые мне нужно использовать?

Ответы [ 5 ]

113 голосов
/ 03 января 2012

Считайте содержимое двоичного файла следующим образом:

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:])

22 голосов
/ 03 января 2012

В общем, я бы порекомендовал вам использовать для этого модуль Python struct . Это стандартно для Python, и должно быть легко перевести спецификацию вашего вопроса в строку форматирования, подходящую для struct.unpack().

Обратите внимание, что если между полями или вокруг них есть «невидимые» отступы, вам необходимо выяснить это и включить их в вызов unpack(), иначе вы прочитаете неправильные биты.

Чтение содержимого файла, чтобы что-то распаковать, довольно тривиально:

import struct

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

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

Распаковывает первые два поля, предполагая, что они начинаются в самом начале файла (без заполнения или посторонних данных), а также предполагая собственный порядок байтов (символ @). Символ I в строке форматирования означает «целое число без знака, 32 бита».

11 голосов
/ 03 января 2012

Вы можете использовать numpy.fromfile, который может считывать данные как из текстовых, так и из двоичных файлов.Сначала вы должны сконструировать тип данных, который представляет ваш формат файла, используя numpy.dtype, а затем прочитать этот тип из файла, используя numpy.fromfile.

1 голос
/ 03 ноября 2018

Чтобы прочитать двоичный файл в объект 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 с из данных:

import struct
ints = struct.unpack('iiii', data[:16])
0 голосов
/ 13 декабря 2017
import pickle
f=open("filename.dat","rb")
try:
    while True:
        x=pickle.load(f)
        print x
except EOFError:
    pass
f.close()
...