9

我已经使用 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?

4

4 回答 4

12

我讨厌这样做,但我觉得如果我希望在这篇文章中找到答案,那么前进的道路就不清楚了。所以这是前进的道路。

短版

在 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 页眉和页脚的顺序访问文件。

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

Bishop University 的 Lin Jinsen 的精彩页面(非常感谢)。

IBM 为其编译器提供的更多官方文档。

于 2012-04-04T19:34:38.003 回答
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
于 2012-04-03T17:41:11.837 回答
1

您可以告诉open在 Fortran 2003 中使用新的 Stream IO 模式和access='stream'.

于 2012-04-03T17:38:19.333 回答
1

如果不能使用流访问,则必须使用直接访问。请参阅此问题的答案链接。

于 2012-04-03T19:53:08.350 回答