使用Python将二进制数据写入文件

Sch*_*fer 7 python binary file python-3.x

我试图将数据(文本,浮点数据)写入二进制文件,稍后由另一个程序读取.问题是这个程序(在Fort95中)非常特别; 每个字节必须位于正确的位置才能正确读取文件.我已经尝试使用Bytes对象和.encode()来编写,但没有太多运气(我可以从文件大小告诉它正在编写额外的数据字节).我试过的一些代码:

mgcnmbr='42'
bts=bytes(mgcnmbr)
test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(bts)
test_file.close()
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

mgcnmbr='42'
bts=mgcnmbr.encode(utf_32_le)
test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(bts)
test_file.close()
Run Code Online (Sandbox Code Playgroud)

为了澄清,我需要的是整数值42,写为4字节二进制.接下来,我会用4字节二进制写入数字1和0.那时,我应该有12个字节.每个都是一个4字节有符号整数,用二进制写.我对Python很陌生,似乎无法解决这个问题.有什么建议?像这样的东西?我需要完全控制每个整数(以及后来的4字节浮点)的字节数.

谢谢

M.J*_*urn 15

你需要struct模块.

import struct

fout = open('test.dat', 'wb')

fout.write(struct.pack('>i', 42))
fout.write(struct.pack('>f', 2.71828182846))

fout.close()
Run Code Online (Sandbox Code Playgroud)

struct.pack中的第一个参数是格式字符串.

格式字符串中的第一个字符指示数据的字节顺序或字节顺序(首先存储最重要或最不重要的字节 - big-endian或little-endian).字节顺序因系统而异.如果">"不起作用,请尝试"<".

格式字符串中的第二个字符是数据类型.不出所料,"i"代表整数,"f"代表浮点数.字节数由类型决定.例如,短裤或"h"是两个字节长.还有无符号类型的代码.例如,"H"对应于无符号短路.

struct.pack中的第二个参数当然是要包装到bytes对象中的值.

这是我告诉你的一部分,我撒了几件事.首先我说的是字节数由类型决定.这只是部分正确.给定类型的大小在技术上是平台相关的,因为C/C++标准(结构模块所基于的)仅指定最小大小.这引出了我的第二个谎言.格式字符串中的第一个字符还编码是使用标准(最小)字节数还是本机(平台相关)字节数.(">"和"<"都保证使用标准的最小字节数,在整数"i"或浮点"f"的情况下实际上是4.)它还对数据的对齐进行编码.

struct模块文档包含格式字符串参数的表.

您还可以将多个基元打包到单个字节对象中,并实现相同的结果.

import struct

fout = open('test.dat', 'wb')

fout.write(struct.pack('>if', 42, 2.71828182846))

fout.close()
Run Code Online (Sandbox Code Playgroud)

您当然可以使用struct.unpack解析二进制数据.

  • 这是正确的事情。只是一个额外的提示:使用 `with` 语句来避免忘记 `close`! (2认同)

Alg*_*ary 0

假设您希望它采用小端字节序,您可以执行类似的操作,将 42 写入四字节二进制文件中。

test_file=open(PATH_HERE/test_file.dat','ab')
test_file.write(b'\xA2\0\0\0')
test_file.close()
Run Code Online (Sandbox Code Playgroud)

A2 的十六进制为 42,字节'\xA2\0\0\0'使第一个字节等于 42,后跟三个空字节。此代码写入字节:42,0,0,0。

您的代码写入字节来表示 UTF 32 中的字符“4”,写入字节来表示 UTF 32 中的 2。这意味着它写入字节:52, 0, 0, 0, 50, 0, 0, 0,因为每个以 UTF 32 编码时,字符为四个字节。

另外,使用十六进制编辑器进行调试可能对您很有用,然后您可以看到程序输出的字节而不仅仅是大小。