使用struct.pack和struct.unpack_from写入数据结构不正确

时间:2014-02-20 14:52:49

标签: python python-2.7

我在二进制文件中获取数据时遇到此问题

# Write data
f = open(path, 'wb')

start_date = [2014, 1, 1, 0, 0, 0, 0]
end_date = [2014, 2, 1, 0, 0, 0, 0]

for x in range(10):
    f.write(struct.pack('B', 0))
    f.write(struct.pack('I', x))
    f.write(struct.pack('HBBBBBH', *start_date_binary))
    f.write(struct.pack('HBBBBBH', *end_date_binary))

f.close()

# Read data
f = open(path, 'rb')
for x in range(10):
    data_structure = struct.unpack_from("BIHBBBBBHHBBBBBH",
                                        f.read(FILE_INDEX_STRUCTURE))
    print(data_structure)

f.close()

输出

(0, 0, 2014, 1, 1, 0, 0, 0, 0, 56832, 7, 2, 1, 0, 0, 0)
(0, 17292800, 1, 0, 0, 0, 0, 0, 2014, 258, 0, 0, 0, 0, 0, 0)
(7, 257, 0, 0, 0, 222, 7, 2, 1, 0, 0, 0, 0, 0, 3, 0)
(0, 0, 56832, 7, 2, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2014)
(0, 131989504, 258, 0, 0, 0, 0, 0, 0, 5, 0, 0, 222, 7, 1, 1)
(222, 66055, 0, 0, 0, 0, 0, 6, 0, 56832, 7, 1, 1, 0, 0, 0)
(1, 0, 0, 0, 7, 0, 0, 0, 2014, 257, 0, 0, 0, 0, 0, 56832)
(0, 0, 8, 0, 0, 222, 7, 1, 1, 0, 0, 0, 0, 222, 7, 258)
(0, 2304, 56832, 7, 1, 1, 0, 0, 0, 0, 222, 7, 2, 1, 0, 0)  

预期输出是

(0, 0, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 1, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 2, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 3, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 4, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 5, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 6, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 7, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 8, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)
(0, 9, 2014, 1, 1, 0, 0, 0, 0, 2014, 2, 1, 0, 0, 0, 0)

修改

获取'B'为1且'H'为2的项的结构类型。在同一unpack函数中使用这些类型时,类型会混淆,例如{{1} }是3但返回4.

'BH'

1 个答案:

答案 0 :(得分:6)

您遇到了填充问题。正如docs所说:

  

填充仅在连续的结构成员之间自动添加。在编码结构的开头或结尾没有添加填充。

看看发生了什么:

>>> struct.pack("B", 0)
'\x00'
>>> struct.pack("I", 1)
'\x01\x00\x00\x00'
>>> struct.pack("BI", 0, 1)
'\x00\x00\x00\x00\x01\x00\x00\x00'

所以你不能单独包装物品,然后将它们拆开包装,除非你自己添加填充物......

>>> struct.pack("B0I", 0)
'\x00\x00\x00\x00'

或完全关闭填充:

>>> struct.pack("=BI", 0, 1)
'\x00\x01\x00\x00\x00'
相关问题