简单读取fortran二进制数据在python中不那么简单

2024-09-29 01:24:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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)

很好。但这是一个很大的文件,我需要做得更有效。所以我试着:

^{pr2}$

不会跑的。给我一个错误,告诉我unpack需要一个长度为20的参数。自从上次我检查的时候,4+8+4=16,这对我来说毫无意义。当我放弃并用20代替16时,它会运行,但是这三个数字都是数字垃圾。有人看到我做错什么了吗?谢谢!在


Tags: 文件代码文本read选项记录二进制数字
3条回答

我建议使用数组来读取由FORTRAN编写的无格式、顺序的文件。在

使用数组的具体示例如下:

import array
binfile=open('myfile','rb')
pad = array.array('i')
ver = array.array('d')
pad.fromfile(binfile,1)   # read the length of the record 
ver.fromfile(binfile,1)   # read the actual data written by FORTRAN
pad.fromfile(binfile,1)   # read the length of the record

如果您有FORTRAN记录来编写整数和双精度数组,这是非常常见的,那么您的python将如下所示:

^{pr2}$

最后一点是,如果文件中有字符,也可以将其读入数组,然后将其解码为字符串。像这样:

import array
binfile=open('myfile','rb')
pad = array.array('i')
my_characters = array.array('B')
number_of_characters = 63 # replace with number of characters to read
pad.fromfile(binfile,1)   # read the length of the record 
my_characters.fromfile(binfile,number_of_characters ) # read the data
my_string = my_characters.tobytes().decode(encoding='utf_8') 
pad.fromfile(binfile,1)   # read the length of the record

您得到的大小是由对齐引起的,请尝试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;
}

double条目需要8字节对齐,以便在大多数CPU负载操作中高效(甚至正确)工作。这就是为什么在int1和{}之间添加4个字节的填充,这将结构的大小增加到20个字节。相同的填充由struct模块执行,除非您通过在小端计算机上添加<(在小端计算机上)或{}(在大端计算机上)来抑制填充,或者只在格式字符串的开头添加{}:

^{pr2}$

d是由16个随机字符组成的字符串。)

相关问题 更多 >