我正在编写一个 python3 脚本来将一些数字作为二进制文件写入文件。在做的过程中,我发现了一些很奇怪的事情。例如,以下 python 代码将“unsign short”和“float”数字写入 tmp 文件:
import struct
with open('tmp', "wb") as f:
id1 = 1
i = 0.5785536878880112
fmt = "Hf"
data = struct.pack('Hf', id1, i)
f.write(data)
print("no. of bytes:%d"%struct.calcsize(fmt))
Run Code Online (Sandbox Code Playgroud)
根据文档“H”(无符号短)是 2 个字节,“f”(浮点数)是 4 个字节。所以我期望一个 6 字节的文件,但是输出是一个 8 字节的数据:
01 00 00 00 18 1c 14 3f
Run Code Online (Sandbox Code Playgroud)
正如所指出的
struct.calcsize(fmt)
Run Code Online (Sandbox Code Playgroud)
其中说“Hf”的大小为 8 个字节
如果我分开做,例如
data = struct.pack('H', id1)
f.write(data)
data = struct.pack('f', i)
f.write(data)
Run Code Online (Sandbox Code Playgroud)
那么输出是一个预期的 6 字节文件:
01 00 18 1c 14 3f
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
根据文档,指定字节顺序会删除任何填充:
使用非本机大小和对齐时不添加填充,例如使用“<”、“>”、“=”和“!”。
因此,假设您需要 little endian 打包,以下给出了所需的输出:
>>> struct.pack('<Hf', id1, i)
'\x01\x00\x18\x1c\x14?'
Run Code Online (Sandbox Code Playgroud)
请注意<. (3f可以编码为 ASCII ?,因此替换)