2010-04-23 6 views
6

Lesen habe ich eine Datei, die mit der folgenden Delphi Erklärung ... eine Delphi Binär-Datei in 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; 

Ich möchte die Daten in den Dateien (viele MB groß) analysieren mit Python

geschrieben wurde, wenn möglich - gibt es eine einfache Möglichkeit, die Daten einzulesen und die Daten in Python-Objekte umzuwandeln, die den Delphi-Datensätzen ähnlich sind? Kennt jemand vielleicht eine Bibliothek, die das tut?

Dies wird auf Delphi 7 mit den folgenden Optionen zusammengestellt, die (oder auch nicht), relevant sein können

  • Satzfeld Ausrichtung: 8
  • Pentium Sicher FDIV: False
  • Stack-Frames: False
  • Optimierung: Echte
+1

Eine Sache, die Sie brauchen, um herauszufinden, was 'Real' den Zeitcode der Delphi gemeint kompiliert wurde. In neueren Code ist es ein Alias ​​für 'Double', die normale IEEE 64-Bit Gleitkommazahl. In älteren Delphi-Versionen war es das, was heute als 'Real48' bekannt ist, das ich nirgendwo anders gesehen hatte (obwohl es hier einige Fragen zu Stack Overflow gab, um diese 6-Byte-Typen in C# zu' double' zu ​​konvertieren, was für Ihre eigenen Bemühungen nützlich sein kann). –

+1

Wissen Sie, mit welcher Delphi-Version das kompiliert wurde? – PhiS

+0

Der Code wurde in Delphi 7 – Brendan

Antwort

5

Hier ist die vollständigen Lösungen durch Hinweise von KillianDS und 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

Wenn armax = 5024 dann scheint es, dass Sie einen Fehler nach dem anderen haben. Vielleicht gab es einen Tippfehler und du meintest 5025? –

+0

Ja, das ist richtig, armax = 5025, ich arbeitete aus dem Speicher und ich hatte kürzlich den Wert angepasst, so dass die Datenarrays Null indexiert und verwirrt wurden - ich finde es störend, dass Delphi dynamische/offene Arrays null indiziert noch viele Funktionen (ie Copy()) beginnt bei 1 ... – Brendan

+0

Dynamische Arrays beginnen bei Null, nur Strings beginnen standardmäßig bei 1 (aus historischen Gründen). Wenn Sie ein Array selbst definieren, werden diese Offsets überall verwendet. –

2

ich weiß nicht, wie Delphi intern Daten speichert, aber wenn es so einfach byteweise ist Daten (also nicht serialisiert und gemangelt), verwenden Sie struct. Auf diese Weise können Sie eine Zeichenfolge aus einer Python-Datei als Binärdaten behandeln. Öffnen Sie auch Dateien als binäre file(open,'rb').

2

Bitte beachten Sie, dass bei der Definition eines Datensatzes in Delphi (wie Struktur in C) die Felder in der Reihenfolge und binär in der aktuellen Ausrichtung angeordnet werden (zB Bytes sind auf 1 Byte Grenzen, Wörter auf 2 Byte, Integer) auf 4 byte usw., kann aber bei den Compiler-Einstellungen variieren

Wenn Sie in eine Datei serialisiert werden, meinen Sie wahrscheinlich, dass dieser Datensatz binär in die Datei geschrieben wird und der nächste Datensatz nach dem ersten Datensatz an der Position geschrieben wird sizeof (Struktur) usw. usw. Delphi gibt nicht an, wie die Datei serialisiert werden soll, also lassen uns die Informationen raten

Wenn Sie sicherstellen möchten, dass es immer das gleiche ist w Verwenden Sie ohne Interferenz von Compiler-Einstellungen gepackten Datensatz.

Real kann mehrere Bedeutungen haben (es ist ein 48-Bit-Float-Typ für ältere Delphi-Versionen und später ein 64-Bit-Float (IEEE-Double)).

Wenn Sie nicht auf den Delphi-Code zugreifen oder ihn selbst kompilieren können, überprüfen Sie die Daten mit einem HEX-Editor. Sie sollten die Grenzen der Datensätze deutlich sehen, da sie mit Ganzzahlen beginnen und nur Gleitkommazahlen folgen.

+0

kompiliert Ein Hinweis: Da am Ende der Struktur ein Array-Typ ist, könnte das Array variable Größe haben –

+0

Ich habe Zugriff auf den Code, der liest und schreibt die Daten - so scheint es Im Code selbst sind die einzigen relevanten Zeilen diejenigen in der Frage. Ich habe einige Optionen angegeben, die wichtig erscheinen.Ich habe auch in einem HEX-Editor gesucht, obwohl das für mich unbekanntes Gebiet ist - es gibt viele zufällige Zeichen, die durch große Blöcke von '00'-Zeichen getrennt sind ... – Brendan

+0

Auch die Array-Größe wird mit Konstanten deklariert - armax = 5024 – Brendan