在Fortran中打开二进制文件:状态,表单,访问

the*_*Sin 7 binary file-io fortran fortran77

我多年来一直在使用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
Run Code Online (Sandbox Code Playgroud)

但是,对于没有Fortran标头信息的平面二进制文件,这会如何变化?更重要的是,这里是一个很好的链接更详细地描述这些条款:status,form,access,recl

the*_*Sin 10

我讨厌这样做,但我觉得如果我希望在这篇文章中找到答案,那么前进的方向就不明确了.所以这是前进的方向.

简短版

在Fortran 77/90中,要打开标准的Fortran二进制文件,您可以编写:

OPEN (5, FILE="myFile.txt")
Run Code Online (Sandbox Code Playgroud)

但是要打开一个平坦的非Fortran二进制文件,你必须编写更像这样的东西:

OPEN(5, file="myFile.txt", form='unformatted', access='direct', recl=1)
Run Code Online (Sandbox Code Playgroud)

这种差异是因为Fortran风格的二进制文件在文件中的每个"记录"周围都有一个4字节的页眉和页脚.这些页眉/页脚描述了记录中包含的数据的大小.(在最常见的情况下,您遇到的每个二进制文件只有一条记录.)

长版

Fortran假定了很多默认open参数.实际上,我们的原始示例可以使用以下详细形式编写,以显示假定的所有默认值.

OPEN (5, FILE="myFile.txt") 
OPEN (5, FILE="myFile.txt", FORM="FORMATTED", 
     +   ACCESS="SEQUENTIAL", STATUS="UNKNOWN")
Run Code Online (Sandbox Code Playgroud)

让我们看看每个论点:

  • FORM定义文件是由text(form='formatted')还是二进制数据(form='unformatted')组成.

  • ACCESS定义您是按顺序(access='sequential')或以您想要的任何顺序从文件中读取数据(access='direct').

  • RECL定义进入每条记录的字节数.例如,recl=1只是说记录长度各为1个字节; 也许它们是1字节整数.

  • STATUS定义文件是否已存在.该STATUS="UNKNOWN"参数意味着该文件可能尚不存在,但如果不存在则将创建该文件.如果你想防止写一个旧文件的可能性:STATUS="OLD".同样,如果您知道该文件尚不存在,您将需要使用:STATUS="NEW".

欲获得更多信息:

这些开放语句也会对随后的读/写/关闭语句产生影响.在我的原始帖子中,我需要知道如果您打开直接访问文件,则必须写入直接访问文件.(也就是说,二进制文件中不会包含Fortran页眉/页脚.)但是,Fortran的默认功能是创建包含Fortran页眉和页脚的顺序访问文件.

有关openFortran 77/90中语句的更多信息,有一个很好的在线资源:

毕晓普大学林金森的一个很好的页面(非常感谢你).

IBM为其编译器提供的官方文档略多一些.


use*_*116 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
Run Code Online (Sandbox Code Playgroud)