Python读取二进制文件头遇AttributeError问题及更优实现问询
问题解决与优化方案
一、修复ctypes结构体定义错误
你遇到的AttributeError是因为ctypes结构体中数组字段的定义方式错误。在ctypes里,不能将数组长度写在字段名称中,正确的写法是用类型 * 数组长度来声明数组类型。
修正后的完整代码:
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) ] with open("../data/somefile.bin", mode='rb') as file: result = [] struct_size = sizeof(aircraft_header) allc = aircraft_header() while file.readinto(allc) == struct_size: # 将ctypes数组转为Python列表,方便后续处理 extraint32_list = list(allc.extraint32) extrafloat_list = list(allc.extrafloat) # 解码字符串并去除末尾的空终止符 aircraft_name = allc.aircraft_name.decode('utf-8').rstrip('\x00') result.append(( allc.message_time, allc.lon, allc.lat, allc.alt, extraint32_list, extrafloat_list, aircraft_name ))
二、更Pythonic的二进制文件读取方式
使用Python标准库的struct模块是更轻量化、更符合Python风格的方案,无需定义结构体类,直接通过格式字符串解析二进制数据:
import struct # 定义格式字符串:Q=uint64, f=float, i=int32, s=char数组 # 可根据实际字节序添加前缀:<小端,>大端,=本机字节序(默认) fmt = 'Qfff16i16f100s' struct_size = struct.calcsize(fmt) with open("../data/somefile.bin", mode='rb') as file: result = [] # 使用海象运算符简化循环(Python 3.8+支持) while chunk := file.read(struct_size): if len(chunk) != struct_size: break # 跳过文件末尾不完整的结构体数据 unpacked_data = struct.unpack(fmt, chunk) # 提取各字段数据 message_time = unpacked_data[0] lon, lat, alt = unpacked_data[1:4] extraint32 = list(unpacked_data[4:20]) # 16个int32对应索引4-19 extrafloat = list(unpacked_data[20:36]) # 16个float对应索引20-35 aircraft_name = unpacked_data[36].decode('utf-8').rstrip('\x00') result.append(( message_time, lon, lat, alt, extraint32, extrafloat, aircraft_name ))
两种方案对比
- ctypes:适合需要和C代码交互、复用C结构体定义的场景,对C开发者更友好。
- struct:更轻量,代码更简洁,无需额外定义类,纯Python风格,适合仅需解析二进制文件的场景。
内容的提问来源于stack exchange,提问作者pookie
相关产品推荐
相关产品推荐

