我多年来一直在使用Fortran,但文件I / O对我来说仍然很模糊。我对status
,form
,access
,recl
的理解是有限的,因为我只需要在研究生院中使用某些用例。 />
我知道Fortran二进制文件在文件顶部有额外的信息来描述文件的大小。但这对我来说从来就不是一个问题,因为我只需要处理Fortran代码中的Fortran文件,其中额外的信息是必要的,但是看不见。
但是如何在Fortran中打开一个平面的二进制文件?
过去,我可以通过这样的方式使用Fortran打开Fortran二进制文件:
open(id,file=file_name,status='old',
+ form='unformatted',access='direct',recl=4,iostat=ok)
if (ok .ne. 0) then
write(1,20) id,ok,file_name
else
write(1,21) id,file_name
但是,对于没有Fortran标头信息的平面二进制文件,这会如何变化?更重要的是,哪里有更好的链接来更详细地描述这些术语:status
,form
,access
,recl
?
答案 0 :(得分:10)
我讨厌这样做,但我觉得如果我希望在这篇文章中找到答案,那么前进的方向就不明确了。所以这是前进的方向。
短版
在Fortran 77/90中,要打开标准的Fortran二进制文件,您可以写一下:
OPEN (5, FILE="myFile.txt")
但是要打开一个平坦的非Fortran二进制文件,你必须写一些更像这样的东西:
OPEN(5, file="myFile.txt", form='unformatted', access='direct', recl=1)
这种差异是因为Fortran风格的二进制文件在文件中的每个“记录”周围都有一个4字节的页眉和页脚。这些页眉/页脚描述了记录中包含的数据的大小。 (在最常见的情况下,您遇到的每个二进制文件只有一条记录。)
长版
Fortran假定有很多默认open
个参数。实际上,我们的原始示例可以用以下详细形式编写,以显示所有默认值。
OPEN (5, FILE="myFile.txt")
OPEN (5, FILE="myFile.txt", FORM="FORMATTED",
+ ACCESS="SEQUENTIAL", STATUS="UNKNOWN")
让我们看看每个论点:
FORM 定义文件是由文本(form='formatted'
)还是二进制数据(form='unformatted'
)组成。
ACCESS 定义您是按顺序(access='sequential'
)还是以任何顺序(access='direct'
)读取文件中的数据。
RECL 定义进入每条记录的字节数。例如,recl=1
只是说记录长度各为1个字节;也许它们是1字节整数。
STATUS 定义文件是否已存在。 STATUS="UNKNOWN"
参数表示该文件可能尚不存在,但如果不存在,则会创建该文件。如果您想要防止使用旧文件进行书写,请使用:STATUS="OLD"
。同样,如果您知道该文件尚不存在,则需要使用:STATUS="NEW"
。
更多信息:
这些开放语句也会对随后的读/写/关闭语句产生影响。在我的原始帖子中,我需要知道如果您打开直接访问文件,则必须写入直接访问文件。 (也就是说,二进制文件中不会包含Fortran页眉/页脚。)但是,Fortran的默认功能是创建包含Fortran页眉和页脚的顺序访问文件。
有关Fortran 77/90中open
语句的更多信息,有一个很好的在线资源:
A nice page(非常感谢你)。
IBM为其编译器答案 1 :(得分:5)
有一点需要注意:recl
中给出的记录长度默认为4字节字数与未格式化的记录(至少在英特尔编译器上,使用byterecl
另有说明),所以你可能有指定编译器选项或使用recl=1
。
正如您的代码所代表的那样,使用无格式和直接代码,您需要做的就是确保正确读取数据,这就是选择合适的记录长度。但是,有些FORTRAN编译器并不总是对未格式化的二进制文件很好,我建议继续使用HDF5。
如果可用,您的编译器可能允许recordtype='stream'
:
open (id, file=file_name, status='old', form='unformatted' &
, access='stream', iostat=ios)
! read (id, pos=1) someValue
答案 2 :(得分:2)
您可以告诉open
使用带有access='stream'
的Fortran 2003中的新Stream IO模式。
答案 3 :(得分:1)
如果您无法使用流访问,则必须使用直接访问。请参阅回答this question的链接。