【发布时间】:2016-01-26 05:58:28
【问题描述】:
我有一个使用 Python 代码创建的二进制文件。这段代码主要是编写一堆任务来预处理一组数据文件。我现在想在 Fortran 中读取这个二进制文件。二进制文件的内容是简单格式的点坐标,例如:点数,x0, y0, z0, x1, y1, z1, ....
这些二进制文件是使用 numpy 中的“tofile”函数创建的。到目前为止,我在 Fortran 中有以下代码:
integer:: intValue
double precision:: dblValue
integer:: counter
integer:: check
open(unit=10, file='file.bin', form='unformatted', status='old', access='stream')
counter = 1
do
if ( counter == 1 ) then
read(unit=10, iostat=check) intValue
if ( check < 0 ) then
print*,"End Of File"
stop
else if ( check > 0 ) then
print*, "Error Detected"
stop
else if ( check == 0 ) then
counter = counter + 1
print*, intValue
end if
else if ( counter > 1 ) then
read(unit=10, iostat=check) dblValue
if ( check < 0 ) then
print*,"End Of File"
stop
else if ( check > 0 ) then
print*, "Error Detected"
stop
else if ( check == 0 ) then
counter = counter + 1
print*,dblValue
end if
end if
end do
close(unit=10)
不幸的是,这不起作用,我得到了垃圾号码(例如 6.4731191026611484E+212、2.2844499004808491E-279 等)。有人可以就如何正确执行此操作提供一些指示吗? 还有什么是在 Python 和 Fortran 之间可互换地编写和读取二进制文件的好方法——因为这似乎将成为我的应用程序的要求之一。
谢谢
【问题讨论】:
-
我添加了一个很好的详细答案,告诉你使用
access=stream:) 我刚刚意识到你已经这样做了,所以我现在删除了我的答案。所以,问题:你确定你的 pythonint和你的 fortraninteger的字节大小是一样的吗?你应该检查两者。如果有单个字节的差异,数据的错位会导致reading 之后的垃圾。你用的是什么fortran编译器?你如何声明你的integers?你的 pythonints 的具体类型是什么? -
如果您真的很绝望,您可以尝试使用 fortran 和 python 生成(假设)相同的虚拟二进制文件,然后查看这两个文件的十六进制转储以查看发生了什么。此外,我之前关于
integer大小的问题显然也适用于所涉及的doubles。即使类型检查出来,如果您在两台非常不同的机器上使用这两个代码,仍然可能存在字节顺序问题。 -
关于互换性的问题:我宁愿把点数之类的元数据放到一个单独的ASCII头文件中,方便阅读,只把同类数据放到一个二进制文件中,这也允许相当容易的字节序转换。
-
为了便携性和可互换性,我会使用 HDF5 来读取/写入数据。支持 python 和 Fortran 以及许多其他。
-
种类数字通常是不可移植的,但
kind=32对我知道的所有编译器都无效。使用kind=real32和kind=real64(常量来自模块iso_fortran_envgcc.gnu.org/onlinedocs/gfortran/ISO_005fFORTRAN_005fENV.html)。它们应该等同于 NumPy float32 和 float64。
标签: python fortran binaryfiles