简体   繁体   English

用Python读取Delphi二进制文件

[英]Reading a Delphi binary file in Python

I have a file that was written with the following Delphi declaration ... 我有一个用以下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;

I want to analyse the data in the files (many MB in size) using Python if possible - is there an easy way to read in the data and cast the data into Python objects similar in form to the Delphi records? 如果可能,我想使用Python分析文件中的数据(大小为MB) - 是否有一种简单的方法来读取数据并将数据转换为类似于Delphi记录的Python对象? Does anyone know of a library perhaps that does this? 有没有人知道图书馆可能这样做?

This is compiled on Delphi 7 with the following options which may (or may not) be pertinent, 这是在Delphi 7上编译的,其中包含以下可能(或可能不)相关的选项,

  • Record Field Alignment: 8 记录字段对齐:8
  • Pentium Safe FDIV: False 奔腾安全FDIV:错误
  • Stack Frames: False 堆栈框架:错误
  • Optimization: True 优化:真的

Here is the full solutions thanks to hints from KillianDS and Ritsaert Hornstra 以下是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:]

I do not know how Delphi internally stores data, but if it is as simple byte-wise data (so not serialized and mangled), use struct . 我不知道Delphi如何在内部存储数据,但如果它是简单的逐字节数据(因此不是序列化和损坏的),请使用struct This way you can treat a string from a python file as binary data. 这样,您可以将python文件中的字符串视为二进制数据。 Also, open files as binary file(open,'rb') . 此外,打开文件作为二进制file(open,'rb')

Please note that when you define a record in Delphi (like struct in C) the fields are layed out in order and in binary given the current alignment (eg Bytes are aligned on 1 byte boundaries, Words on 2 byte, Integers on 4 byte etc, but it may vary given the compiler settings. 请注意,当您在Delphi中定义记录时(如C中的struct),字段按顺序排列,并以二进制形式给出当前对齐(例如,字节在1字节边界上对齐,字节在2字节上,整数在4字节上等,但根据编译器设置,它可能会有所不同。

When serialized to a file, you probably mean that this record is written in binary to the file and the next record is written after the first one starting at position sizeof( structure) etc etc. Delphi does not specify how thing should be serialized to/from file, So the information you give leaves us guessing. 当序列化为文件时,您可能意味着该记录以二进制形式写入文件,而下一条记录是在第一个从位置sizeof(结构)等开始写入之后等等.Delphi没有指定应该如何序列化/来自档案,所以你提供的信息让我们猜测。

If you want to make sure it is always the same without interference of any compiler setings, use packed record. 如果要确保它始终相同而不受任何编译器设置的干扰,请使用打包记录。

Real can have multiple meanings (it is an 48 bit float type for older Delphi versions and later on a 64 bit float (IEEE double)). Real可以有多种含义(对于较旧的Delphi版本,它是48位浮点型,后来是64位浮点数(IEEE double))。

If you cannot access the Delphi code or compile it yourself, just ty to check the data with a HEX editor, you should see the boundaries of the records clearly since they start with Integers and only floats follow. 如果您无法访问Delphi代码或自行编译,只需使用HEX编辑器检查数据,您应该清楚地看到记录的边界,因为它们以Integers开头,只有浮点数跟随。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM