2010-04-23 3 views
6

У меня есть файл, который был записан с помощью следующей декларации Delphi ...Чтение двоичного файла Delphi в Python


Type 
    Tfulldata = Record 
    dpoints, dloops : integer; 
    dtime, bT, sT, hI, LI : real; 
    tm : real; 
    data : array[1..armax] Of Real; 
    End; 

... 
Var: 
    fh: File Of Tfulldata; 

Я хочу, чтобы анализировать данные в файлах (много МБ) с помощью Python, если возможно - есть ли простой способ прочитать данные и передать данные в объекты Python, похожие по форме на записи Delphi? Может кто-нибудь знает о библиотеке, возможно, это делает это?

Это составлена ​​на Delphi 7 со следующими параметрами, которые могут (или не могут) иметь отношение,

  • Запись поле Выравнивание: 8
  • Pentium Safe FDIV: Ложные
  • Stack Frames: Ложные
  • Оптимизация: Правда
+1

Одна вещь, вы должны выяснить, является то, что 'Real' означает, в то время код Delphi был составлен. В более новом коде это псевдоним для «Double», обычного 64-битного числа с плавающей запятой IEEE. В более старых версиях Delphi это было то, что в наши дни известно как «Real48», которое я никогда не видел нигде (хотя в Stack Overflow было несколько вопросов о преобразовании этих 6-байтных типов в 'double' в C#, которые могут быть полезны в ваших собственных усилиях). –

+1

Знаете ли вы, с какой версией Delphi это было скомпилировано? – PhiS

+0

Код был скомпилирован в Delphi 7 – Brendan

ответ

5

Вот полные решения, благодаря намекам из KillianDS и Ritsaert Hornstra

import struct 
fh = open('my_file.dat', 'rb') 
s = fh.read(40256) 
vals = struct.unpack('iidddddd5025d', s) 
dpoints, dloops, dtime, bT, sT, hI, LI, tm = vals[:8] 
data = vals[8:]
+1

Если armax = 5024, то, похоже, у вас есть ошибка за один раз. Может, была опечатка, а вы имели в виду 5025? –

+0

Да, это правильно, armax = 5025, я работал с памятью, и я недавно скорректировал значение, чтобы массивы данных были проиндексированы нулями и запутались - я нахожу это раздражающим, что у Delphi есть динамические/открытые массивы с нулевой индексацией, но многие функции (т.е. Copy()) начинаются с одного ... – Brendan

+0

Динамические массивы начинаются с нуля, только строки начинаются с 1 по умолчанию (из-за исторических причин). Когда вы сами определяете массив, эти смещения используются повсюду. –

2

Я не знаю, как Delphi внутренне хранит данные, но если это так просто побайтно данные (поэтому не сериализованные и искаженные), используйте struct. Таким образом, вы можете обрабатывать строку из файла python в виде двоичных данных. Также открывайте файлы как двоичные файлы file(open,'rb').

2

Пожалуйста, обратите внимание, что при определении записи в Delphi (например, структуры в C) поля укладываются в порядке и в двоичной системе с учетом текущего выравнивания (например Байты выровнены по границам 1 байт, слова на 2 байта, Integer, на 4 байта и т. д., но он может меняться в зависимости от настроек компилятора.

При сериализации в файл вы, вероятно, имеете в виду, что эта запись записывается в двоичном виде в файл, а следующая запись записывается после первого запуска в позицию sizeof (структура) и т. д. и т. д. Delphi не указывает, как вещи должны быть сериализованы в/из файла. Таким образом, информация, которую вы даете, оставляет нам угадывание.

Если вы хотите убедиться, что он всегда один и тот же w без вмешательства каких-либо параметров компилятора, используйте упакованную запись.

Реальный может иметь несколько значений (это 48-битный тип с плавающей точкой для старых версий Delphi и более поздний вариант с 64-битным поплавком (IEEE double)).

Если вы не можете получить доступ к коду Delphi или скомпилировать его самостоятельно, просто проверьте данные с помощью редактора HEX, вы должны четко видеть границы записей, так как они начинаются с целых чисел, и следуют только поплавки.

+0

Одно примечание: поскольку в конце структуры существует тип массива, массив может быть переменным размером –

+0

У меня есть доступ к коду, который читает и записывает данные - кажется, что в самом коде единственными подходящими строками являются те, что в вопросе. Я указал некоторые параметры, которые кажутся важными.Я также посмотрел в редакторе HEX, хотя для меня это незнакомая территория - есть множество случайных символов, разделенных большими блоками символов «00» ... – Brendan

+0

Также размер массива объявлен с константой - armax = 5024 – Brendan

Смежные вопросы