Home > Software engineering >  Reading a binary file header with Python
Reading a binary file header with Python

Time:09-15

I have some binary data that I want to read via Python. I have the C code to do this, but I want to try it in Python.

Let's say the header of the file is as follows:

typedef struct
{
    uint64_t    message_time;           
    float       lon, lat, alt;  
    int32_t     extraint32[16]; 
    float       extrafloat[16]; 
    char        aircraft_name[100];     
} AIRCRAFT_HEADER;

Using Python, I do the following:

from ctypes import *

class aircraft_header(Structure):
    _fields_ = [('message_time', c_uint64),
                ('lon', c_float), ('lat', c_float), ('alt', c_float),
                ('extraint32[16]', c_int32),
                ('extrafloat[16]', c_float),
                ('aircraft_name[100]', c_char)
                ]

with open("../data/somefile.bin",mode='rb') as file:
    result = []
    allc = aircraft_header()
    while file.readinto(allc) == sizeof(allc):
        result.append((allc.message_time,
                       allc.lon, allc.lat, allc.alt,
                       allc.extraint32,
                       allc.extrafloat,
                       allc.aircraft_name))

This will throw the exception:

AttributeError: 'aircraft_header' object has no attribute 'extraint32'

How do I resolve this? Also, is there a more Pythonic way of reading this binary file?

CodePudding user response:

Take a look at the attributes available on an aicraft_header object:

>>> example = aircraft_header()
>>> [x for x in dir(example) if not x.startswith('_')]
['aircraft_name[100]', 'alt', 'extrafloat[16]', 'extraint32[16]', 'lat', 'lon', 'message_time']

You have an attribute that is named literally extraint32[16], which suggests you have an error in how your definining your Structure.

Taking a look at ctypes documentation, I think you want:

from ctypes import *

class aircraft_header(Structure):
    _fields_ = [('message_time', c_uint64),
                ('lon', c_float), ('lat', c_float), ('alt', c_float),
                ('extraint32', c_int32 * 16),
                ('extrafloat', c_float * 16),
                ('aircraft_name', c_char * 100)
                ]

This appears to behave as expected:

>>> example.extraint32
<__main__.c_int_Array_16 object at 0x7fda7c9068c0>
>>> example.extraint32[0]
0
>>> example.extraint32[15]
0
>>> example.extraint32[16]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: invalid index
  • Related