代码之家  ›  专栏  ›  技术社区  ›  Brendan

在python中读取delphi二进制文件

  •  6
  • Brendan  · 技术社区  · 16 年前

    我有一个文件是用下面的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;
    

    如果可能的话,我想使用python分析文件中的数据(许多MB大小)-是否有一种简单的方法来读取数据并将数据转换成类似于delphi记录的python对象?有人知道图书馆可能会这样吗?

    这是在Delphi7上编译的,具有以下可能(或不可能)相关的选项,

    • 记录字段对齐:8
    • Pentium Safe FDIV:错误
    • 堆栈帧:假
    • 优化:真
    3 回复  |  直到 16 年前
        1
  •  5
  •   Brendan    16 年前

    以下是完整的解决方案,这要感谢基里安兹和里萨特·霍恩斯特拉的暗示。

    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:]
        2
  •  2
  •   KillianDS    16 年前

    我不知道Delphi是如何在内部存储数据的,但是如果它是简单的字节级数据(因此不序列化和损坏),请使用 struct . 这样就可以将python文件中的字符串视为二进制数据。另外,以二进制方式打开文件 file(open,'rb') .

        3
  •  2
  •   Ritsaert Hornstra    16 年前

    请注意,在Delphi中定义记录(如C中的struct)时,字段按照当前对齐方式(如字节在1字节边界上对齐、单词在2字节上对齐、整数在4字节上对齐等)的顺序和二进制进行布局,但在编译器设置的情况下,可能会有所不同。

    当序列化到一个文件时,您可能意味着这个记录是以二进制形式写入文件的,而下一个记录是在第一个记录之后写入的,从位置sizeof(结构)等开始。delphi没有指定应该如何序列化到/从文件,因此您提供的信息让我们猜测。

    如果您想确保它总是相同的,而不受任何编译器设置的干扰,请使用压缩记录。

    real可以有多种含义(对于较旧的Delphi版本,它是48位浮点类型,对于较新的64位浮点类型(ieee double))。

    如果您不能访问delphi代码或自己编译它,只需使用十六进制编辑器检查数据,您应该清楚地看到记录的边界,因为它们以整数开始,并且只跟随浮动。