我使用Python将一些文件转换为二进制格式,但我遇到了一个奇怪的陷阱.
import struct
s = struct.Struct('Bffffff')
print s.size
Run Code Online (Sandbox Code Playgroud)
28
Run Code Online (Sandbox Code Playgroud)
显然预期的大小是25,但它似乎将第一个byte(B)解释为某种类型的4字节整数.它还会写出一个4字节的整数而不是一个字节.
存在一种解决方法,即将其分离B为单独的struct,如下所示:
import struct
s1 = struct.Struct('B')
s2 = struct.Struct('ffffff')
print s1.size + s2.size
Run Code Online (Sandbox Code Playgroud)
25
Run Code Online (Sandbox Code Playgroud)
这种行为有什么解释吗?
来自文档
填充仅在连续的结构成员之间自动添加.在编码结构的开头或结尾没有添加填充.
如果你测试
>>> import struct
>>> s1 = struct.Struct('B')
>>> print s1.size
1
>>> s1 = struct.Struct('f')
>>> print s1.size
4
Run Code Online (Sandbox Code Playgroud)
因此,当你添加它是25...但反过来,B是1,其余的是4这样它将被填充,使它4因此答案是28
考虑这个例子
>>> s1 = struct.Struct('Bf')
>>> print s1.size
8
Run Code Online (Sandbox Code Playgroud)
在这里再次B是1和填充3并f是4那么最终它出现于8其中的预期.
如上所述, 要覆盖它,您将不得不使用非本机方法
>>> s1 = struct.Struct('!Bf')
>>> print s1.size
5
Run Code Online (Sandbox Code Playgroud)
使用非原生大小和对齐时不添加填充,例如使用'<','>','='和'!'.
除非您为字节顺序、对齐方式指定任何字符,否则struct请使用本机字节顺序、对齐方式( @); 这会导致填充。
通过显式指定字节顺序,您可以获得您想要的:
>>> struct.Struct('!Bffffff').size # network byte order
25
>>> struct.Struct('=Bffffff').size # native byte order, no alignment.
25
>>> struct.Struct('>Bffffff').size # big endian
25
>>> struct.Struct('<Bffffff').size # little endian
25
>>> struct.Struct('@Bffffff').size # native byte order, alignment. (+ native size)
28
Run Code Online (Sandbox Code Playgroud)