Python破坏了写入磁盘的struct.pack字符串

时间:2013-06-27 17:21:26

标签: python bit-packing

我正在开发一个将二进制数据(整数,双精度,原始字节)写入文件的应用程序。

问题是,数据实际上并没有按照我预期的方式写入文件:

>>> import struct
>>> import io
>>> out = io.open("123.bin", "wb+")
>>> format = "!i"
>>> data = struct.pack(format, 1)
>>> out.write(data)
4L
>>> data
'\x00\x00\x00\x01'
>>> out.close()
>>> infile = io.open("123.bin", "rb")
>>> instr = infile.read()
>>> instr
'\x00\x00\x00\x01'
>>> struct.unpack("!I", instr)
(1,)

所以一切看起来都很好。但经过仔细研究,123.bin文件包含以下内容:

$ hexdump 123.bin 
0000000 0000 0100                              
0000004

所以看起来字节是由io.write()交换的!

python文档说,io.write()接受“给定的字节或bytearray对象”,问题是,struct.pack确实返回str

>>> type(struct.pack(format, 1))
<type 'str'>

那么,我做错了什么?如何在没有任何字符集翻译的情况下将str转换为bytes

3 个答案:

答案 0 :(得分:4)

看起来这是hexdump(1)的奇怪之处。使用xxd(1),我得到......

$ xxd 123.bin
0000000: 0000 0001                                ....

......看起来不错。

您似乎必须使用-C选项才能以合理的格式输出hexdump(1) ...

$ hexdump -C 123.bin
00000000  00 00 00 01                                       |....|
00000004

...或者将其称为hd

答案 1 :(得分:1)

这里的问题不是python,而是hexdump。它将文件中的数据视为16位小端值。您需要做的是告诉hexdump将数据视为8位值。没有查找,我认为这是'-c'选项。

答案 2 :(得分:1)

hexdump的默认输出格式与使用-x选项相同,即根据手册页:

 -x      Two-byte hexadecimal display.  Display the input offset in hexadecimal,
         followed by eight, space separated, four column, zero-filled, two-byte
         quantities of input data, in hexadecimal, per line.

hexdump使用的字节序是架构字节序(这里可能是little-endian),而你要求python以网络顺序存储值(big-endian)。

因此,该值已正确存储,但hexdump错误地解释了该值。您可以使用-C选项或xxd代替hexdump

$ hexdump 123.bin
0000000 0000 0100                              
0000004
$ hexdump -C 123.bin
00000000  00 00 00 01                                       |....|
00000004