2010-04-23 15 views
6

Tengo un archivo que fue escrito con la siguiente declaración Delphi ...La lectura de un archivo binario en Python Delphi


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; 

quiero analizar los datos de los archivos (muchos MB de tamaño) utilizando Python si posible - ¿hay una forma fácil de leer los datos y convertir los datos en objetos de Python de forma similar a los registros de Delphi? ¿Alguien sabe de una biblioteca tal vez que hace esto?

Esto se compila en Delphi 7 con las siguientes opciones que pueden (o no) ser pertinentes,

  • registro de campo Alineación: 8
  • Pentium Segura FDIV: Falso
  • marcos de pila: Falso
  • Optimización: La verdadera
+1

Una cosa que hay que saber es lo que quiere decir 'Real' en el momento en el código Delphi fue compilado. En el código más nuevo, es un alias para 'Doble', el número normal de coma flotante IEEE de 64 bits. En las versiones anteriores de Delphi, era lo que hoy se conoce como 'Real48', que nunca he visto implementado en otro lugar (aunque había un par de preguntas aquí en Stack Overflow sobre la conversión de esos tipos de 6 bytes a' doble' en C#, que puede ser útil en su propio esfuerzo). –

+1

¿Sabe con qué versión de Delphi se compiló? – PhiS

+0

El código fue compilado en Delphi 7 – Brendan

Respuesta

5

Aquí está la solución íntegra gracias a consejos de KillianDS y 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

Si armax = 5024 parece que tienes un error de uno por uno. Tal vez hubo un error tipográfico y te refieres a 5025? –

+0

Sí, es correcto, armax = 5025, estaba trabajando desde la memoria y recientemente había ajustado el valor para que las matrices de datos no estuvieran indexadas y se confundieran. Me resulta molesto que Delphi tenga matrices dinámicas/abiertas sin muchas funciones indexadas (es decir, Copiar()) comienza en uno ... – Brendan

+0

Las matrices dinámicas comienzan en cero, solo las cadenas comienzan en 1 por defecto (debido a razones históricas). Cuando define una matriz usted mismo, esas compensaciones se usan en todas partes. –

2

no sé cómo Delphi internamente almacena los datos, pero si es tan simple byte a byte datos (por lo que no se serializan ni se mutilan), use struct. De esta forma, puede tratar una cadena de un archivo python como datos binarios. Además, abra archivos como binario file(open,'rb').

2

Tenga en cuenta que cuando define un registro en Delphi (como struct en C) los campos se ordenan en binario dada la alineación actual (por ejemplo, bytes están alineados en límites de 1 byte, palabras en 2 bytes, enteros en 4 bytes, etc., pero puede variar según la configuración del compilador.

Cuando se serializa en un archivo, probablemente desee decir que este registro está escrito en binario en el archivo y el siguiente registro se escribe después del primero en la posición sizeof (estructura), etc. Delphi no especifica cómo se serializará la cosa en/desde el archivo, por lo que la información que nos da nos deja adivinar.

Si desea asegurarse de que siempre es la misma w sin interferencia de las selecciones del compilador, utilice el registro empaquetado.

Real puede tener múltiples significados (es un tipo de flotación de 48 bits para las versiones anteriores de Delphi y más tarde para una flotación de 64 bits (IEEE doble)).

Si no puede acceder al código Delphi o compilarlo usted mismo, simplemente para verificar los datos con un editor HEX, debe ver claramente los límites de los registros, ya que comienzan con enteros y solo flotan.

+0

Una nota: Dado que hay un tipo de matriz al final de la estructura, la matriz podría ser de tamaño variable –

+0

Tengo acceso al código que lee y escribe los datos, parece que en el código mismo, las únicas líneas pertinentes son las de la pregunta. He especificado algunas opciones que parecen importantes.También miré en un editor HEX aunque este es un territorio desconocido para mí: hay muchos caracteres aleatorios separados por grandes bloques de caracteres '00' ... – Brendan

+0

También el tamaño de la matriz se declara con constante - armax = 5024 – Brendan

Cuestiones relacionadas