在Python中将二进制数据写入文件
我正在尝试将一些数据(文本和浮点数)以二进制的形式写入一个文件,之后另一个程序会读取这个文件。问题是这个程序(用Fort95写的)对数据的位置要求非常严格;每一个字节必须放在完全正确的位置,才能让文件被正确读取。我尝试使用Bytes对象和.encode()来写入,但效果不太好(从文件大小来看,它写入了多余的字节)。我试过的一些代码如下:
mgcnmbr='42'
bts=bytes(mgcnmbr)
test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(bts)
test_file.close()
我还尝试过:
mgcnmbr='42'
bts=mgcnmbr.encode(utf_32_le)
test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(bts)
test_file.close()
为了更清楚,我需要的是将整数42写成4个字节的二进制形式。接下来,我会将数字1和0也写成4个字节的二进制。到那时,我应该正好有12个字节。每个字节都是一个4字节的有符号整数,以二进制形式写入。我对Python还不太熟悉,似乎无法做到这一点。有没有什么建议?类似于这个?我需要完全控制每个整数(以及后面的4字节浮点数)占用多少字节。
谢谢
3 个回答
在我的问题如何在Python 3.4中将二进制字符串写入二进制文件中,我是这样做的:
file.write(bytes(chr(int(mgcnmbr)), 'iso8859-1'))
假设你想用小端格式来表示数字,你可以这样做,把42写成四个字节的二进制。
test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(b'\xA2\0\0\0')
test_file.close()
A2是42的十六进制表示,字节 '\xA2\0\0\0'
让第一个字节等于42,后面跟着三个空字节。这段代码写出的字节是:42, 0, 0, 0。
你的代码写入的是代表字符'4'和'2'在UTF-32中的字节。这意味着它写出的字节是:52, 0, 0, 0, 50, 0, 0, 0,因为每个字符在UTF-32编码时占用四个字节。
另外,使用十六进制编辑器来调试可能会对你有帮助,这样你就可以看到你的程序输出的字节,而不仅仅是大小。
你需要用到 struct 这个模块。
import struct
fout = open('test.dat', 'wb')
fout.write(struct.pack('>i', 42))
fout.write(struct.pack('>f', 2.71828182846))
fout.close()
在 struct.pack 这个函数里,第一个参数是格式字符串。
格式字符串里的第一个字符决定了数据的字节顺序,也就是 字节序(是把最重要的字节还是最不重要的字节放在前面 - 大端序还是小端序)。字节序在不同的系统中可能会有所不同。如果用 ">" 不行,可以试试 "<"。
格式字符串里的第二个字符表示数据类型。没什么好奇怪的,"i" 代表整数,"f" 代表浮点数。字节的数量是由类型决定的。例如,短整型 "h" 是两个字节长。还有一些代码是用来表示无符号类型的,比如 "H" 代表无符号短整型。
在 struct.pack 中,第二个参数当然就是要打包成字节对象的值。
这里我要告诉你,我之前说的有几件事不太准确。首先,我说字节的数量是由类型决定的,这只是部分正确。实际上,某种类型的大小是和平台有关的,因为 C/C++ 标准(struct 模块就是基于这个标准的)只规定了 最小 大小。这就引出了我的第二个不准确之处。格式字符串里的第一个字符还决定了是使用标准的(最小的)字节数,还是使用本地的(平台相关的)字节数。(">" 和 "<" 都保证使用标准的、最小的字节数,实际上对于整数 "i" 或浮点数 "f" 来说,这个数量都是四个字节。)它还决定了数据的 对齐方式。
struct 模块的文档里有格式字符串参数的表格。
你还可以把多个基本数据类型打包成一个字节对象,得到同样的结果。
import struct
fout = open('test.dat', 'wb')
fout.write(struct.pack('>if', 42, 2.71828182846))
fout.close()
当然,你也可以用 struct.unpack 来解析二进制数据。