我现在很困惑。
如果我打包一个7长度的二进制字符串,结果如下:
>>> struct.pack('7s',b'\x1fBLOCK\n')
b'\x1fBLOCK\n'
此外,如果我打包一个unsigned long long,结果是:
>>> struct.pack('1Q',126208)
b'\x00\xed\x01\x00\x00\x00\x00\x00'
但是,如果我将两者打包在一起,则reuslt会增加一个额外的字节:
>>> struct.pack('7s1Q',b'\x1fBLOCK\n',126208)
b'\x1fBLOCK\n\x00\x00\xed\x01\x00\x00\x00\x00\x00'
任何人都知道为什么会出现这个额外字节?
b' \ x1fBLOCK \ n \ x00 \ x00 \ xed \ x01 \ x00 \ x00 \ x00 \ x00 \ x00'
这个事实破坏了自定义文件的二进制读取......
答案 0 :(得分:2)
struct.pack
生成的字节布局(默认情况下)将与平台C编译器生成的字节匹配,后者可能包括字段之间的填充字节。您可以通过在格式字符串的开头添加=
来禁用此行为:
> struct.pack('7s1Q',b'\x1fBLOCK\n',126208) # C-style layout with padding bytes
'\x1fBLOCK\n\x00\x00\xed\x01\x00\x00\x00\x00\x00'
> struct.pack('=7s1Q',b'\x1fBLOCK\n',126208) # No padding
'\x1fBLOCK\n\x00\xed\x01\x00\x00\x00\x00\x00'
答案 1 :(得分:1)
似乎我使用了@
标志,这意味着字节顺序是本地字节顺序,因此最终大小是可变的。
解决方案在于使用固定大小的标记,例如<
,>
,!
或=
:
>>> struct.pack('<7s1Q',b'\x1fBLOCK\n',126208)
b'\x1fBLOCK\n\x00\xed\x01\x00\x00\x00\x00\x00'
答案 2 :(得分:0)
附加\x00
是字符串终止字节 - 在C中,字符串以\x00
结束。
您将字符串连接到unsigned long long,所以
注意默认情况下,打包给定C结构的结果包括填充字节,以便维护所涉及的C类型的正确对齐
https://docs.python.org/3/library/struct.html#format-characters
b'\x1fBLOCK\n\x00 \x00\xed\x01\x00\x00\x00\x00\x00'
1 23456 7 8th 1 2 3 4 5 6 7 8