Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Reading a binary file header with Python

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading