bob*_*nto 3 python fortran binaryfiles unpack
我有FORTRAN代码的二进制输出文件.想在python中阅读它.(使用FORTRAN读取并输出文本以读取python不是一个选项.长篇故事.)我可以以简单的方式阅读第一条记录:
>>> binfile=open('myfile','rb')
>>> pad1=struct.unpack('i',binfile.read(4))[0]
>>> ver=struct.unpack('d',binfile.read(8))[0]
>>> pad2=struct.unpack('i',binfile.read(4))[0]
>>> pad1,ver,pad2
(8,3.13,8)
Run Code Online (Sandbox Code Playgroud)
正好.但这是一个大文件,我需要更有效地做到这一点.所以我尝试:
>>> (pad1,ver,pad2)=struct.unpack('idi',binfile.read(16))
Run Code Online (Sandbox Code Playgroud)
这不会运行.给我一个错误并告诉我解压缩需要一个长度为20的参数.这对我来说没有任何意义,因为我上次检查时,4 + 8 + 4 = 16.当我输入并用16替换16时,它会运行,但这三个数字都填充了数字垃圾.有谁看到我做错了什么?谢谢!
您获得的大小是由于对齐,尝试struct.calcsize('idi')验证对齐后的大小实际为20.要在不对齐的情况下使用本机字节顺序,请指定struct.calcsize('=idi')并使其适应您的示例.
有关该struct模块的更多信息,请查看http://docs.python.org/2/library/struct.html
该struct模块主要用于与C结构互操作,因此它使数据成员对齐.idi对应于以下C结构:
struct
{
int int1;
double double1;
int int2;
}
Run Code Online (Sandbox Code Playgroud)
double条目需要8字节对齐,以便在大多数CPU加载操作中有效(或甚至正确)运行.这就是为什么在int1和之间添加4个字节的填充double1,这会将结构的大小增加到20个字节.struct模块执行相同的填充,除非您通过添加<(在小端机器上)或>(在大端机器上)或仅=在格式字符串的开头来抑制填充:
>>> struct.unpack('idi', d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 20
>>> struct.unpack('<idi', d)
(-1345385859, 2038.0682530887993, 428226400)
>>> struct.unpack('=idi', d)
(-1345385859, 2038.0682530887993, 428226400)
Run Code Online (Sandbox Code Playgroud)
(d是一串16个随机字符.)