我試圖處理二進制格式,以下這裏的例子:解析二進制數據到ctypes的結構對象
http://dabeaz.blogspot.jp/2009/08/python-binary-io-handling.html
>>> from ctypes import *
>>> class Point(Structure):
>>> _fields_ = [ ('x',c_double), ('y',c_double), ('z',c_double) ]
>>>
>>> g = open("foo","rb") # point structure data
>>> q = Point()
>>> g.readinto(q)
24
>>> q.x
2.0
我定義我的頭的結構我正在嘗試將數據讀入我的結構中,但我遇到了一些困難。 我的結構是這樣的:
class BinaryHeader(BigEndianStructure):
_fields_ = [
("sequence_number_4bytes", c_uint),
("ascii_text_32bytes", c_char),
("timestamp_4bytes", c_uint),
("more_funky_numbers_7bytes", c_uint, 56),
("some_flags_1byte", c_byte),
("other_flags_1byte", c_byte),
("payload_length_2bytes", c_ushort),
]
For integer type fields like c_int, a third optional item can be given. It must be a small positive integer defining the bit width of the field.
所以對於("more_funky_numbers_7bytes", c_uint, 56),
我試圖將該字段定義爲一個字節的7場,但我得到的錯誤:
ValueError: number of bits invalid for bit field
所以我的第一個問題是,我如何定義一個7字節的int字段?
然後如果我跳過這個問題並註釋掉「more_funky_numbers_7bytes」字段,結果數據被載入..但是正如所期望的,只有1個字符被加載到「ascii_text_32bytes」中。並由於某種原因返回16
,我假設它是計算的字節數讀取到結構中......但如果我註釋掉我的「時髦數字」字段和「」ascii_text_32bytes「只給一個字符(1字節) ,不應該說是13,不是16 ???
然後我試圖打破了煤焦領域成爲一個獨立的結構,和參考,從我的頭結構之內。但是,這不是工作要麼...
class StupidStaticCharField(BigEndianStructure):
_fields_ = [
("ascii_text_1", c_byte),
("ascii_text_2", c_byte),
("ascii_text_3", c_byte),
("ascii_text_4", c_byte),
("ascii_text_5", c_byte),
("ascii_text_6", c_byte),
("ascii_text_7", c_byte),
("ascii_text_8", c_byte),
("ascii_text_9", c_byte),
("ascii_text_10", c_byte),
("ascii_text_11", c_byte),
.
.
.
]
class BinaryHeader(BigEndianStructure):
_fields_ = [
("sequence_number_4bytes", c_uint),
("ascii_text_32bytes", StupidStaticCharField),
("timestamp_4bytes", c_uint),
#("more_funky_numbers_7bytes", c_uint, 56),
("some_flags_1byte", c_ushort),
("other_flags_1byte", c_ushort),
("payload_length_2bytes", c_ushort),
]
因此,任何想法如何:
- 定義7字節字段(I'l升無需解碼使用定義的函數)
- 定義的32個字節
UPDATE
我發現,似乎工作結構的靜態字符場...
class BinaryHeader(BigEndianStructure):
_fields_ = [
("sequence_number_4bytes", c_uint),
("ascii_text_32bytes", c_char * 32),
("timestamp_4bytes", c_uint),
("more_funky_numbers_7bytes", c_byte * 7),
("some_flags_1byte", c_byte),
("other_flags_1byte", c_byte),
("payload_length_2bytes", c_ushort),
]
但是現在,我剩下的問題是,爲什麼當使用.readinto()
:
f = open(binaryfile, "rb")
mystruct = BinaryHeader()
f.readinto(mystruct)
它返回52
而不是預期的,51
。那個額外的字節來自哪裏,它到底在哪裏?
UPDATE 2 對於那些有興趣這裏是一個替代struct
方法來讀取值到由eryksun提及namedtuple的example:
>>> record = 'raymond \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)
>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name='raymond ', serialnum=4658, school=264, gradelevel=8)
如果你用一些十六進制編輯器查看你的二進制文件,你看到51個字節嗎?另外,'len(mystruct)'說什麼? –
是的,'binaryfile'超過50KB。 'len(mystruct)'似乎不起作用,但'sizeof(mystruct)'確實返回52 ... – monkut
您可以將'_pack_ = 1'添加到定義中,但考慮使用'struct'模塊和'而不是「namedtuple」。 – eryksun