Fortran可以直接从二进制文件中读取字节吗?

7
我有一个二进制文件,希望用Fortran进行读取。问题是这个文件并不是由Fortran编写的,所以它没有记录长度指示符。因此,通常的非格式化Fortran读取无法完成。
我想到可以通过以格式化方式逐字节(或者每4个字节)将文件读入字符数组中, 然后通过transfer函数或dreaded等效语句将字符内容转换成整数和浮点数。但这种方法行不通:我尝试每次读取4个字节,根据inquire语句的POS输出,读取跳过了大约6000个字节,字符数组中充满了垃圾数据。
所以这个方法不可行。我是否忘记了其中的某些细节?还是在Fortran中有基本不同且更好的方法来处理这个问题?(顺便提一下,我还尝试了将信息读入integer*1数组和byte数组中。尽管这些代码可以编译,但在读取声明时程序会崩溃。)
1个回答

11

是的。

Fortran 2003引入了流访问这一语言特性。在此之前,大多数处理器支持类似于扩展的东西,可能称为“二进制”或类似的名称。

非格式化的流访问在文件上没有施加记录结构。例如,在特定的Fortran处理器中,要从对应于C处理器的单个int的文件中读取数据:

USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
INTEGER, PARAMETER :: unit = 10
CHARACTER(*), PARAMETER :: filename = 'name of your file'
INTEGER(C_INT) :: data
!***
OPEN(unit, filename, ACCESS='STREAM', FORM='UNFORMATTED')
READ (unit) data
CLOSE(unit)
PRINT "('data was ',I0)", data

您可能仍然会遇到字节序和数据类型大小的问题,但这些方面与语言无关。

如果您正在编写Fortran 2003之前的语言标准,则直接访问非格式化读取到适当的整数变量中可能有效 - 它是特定于Fortran处理器的,但适用于许多当前处理器。


非常好!谢谢!我还以为我已经掌握了FORTRAN 90的技能,现在又有更多要学习的了!唉,不过还是非常感谢。 - bob.sacamento
1
没有“流”访问,Fortran读取将一些数据解释为记录长度信息。这既跳过了您想要读取的数据,也导致记录长度错误。此外,该文件在Fortran意义上并没有真正的记录。 - M. S. B.
1
@janneb,是的。在正常格式化读取中,Fortran会填充请求的字符串,然后丢弃记录的其余部分。但是您可以通过使用格式化流IO来覆盖它! - M. S. B.
2
@M. S. B. 非推进输入是为了避免丢弃记录的其余部分所需的。 推进格式化流将文件定位在刚读取的记录之后,方式与推进格式化顺序相同。 格式化流和格式化顺序都存在返回看起来像换行符和/或记录分隔符的字节模式的问题。 - IanH
你没有说你正在使用哪种文件访问和模式。如果你正在使用格式化顺序,那么换行符通常被处理器实现用作记录结束标记(在格式化流中,换行符始终是记录结束)。因此 - 当你请求数据时,处理器会看到记录结束标记,然后相应地发出投诉。你可以尝试使用未格式化的直接访问从文件中读取字节(字符)- 但这取决于你的Fortran处理器如何实现未格式化的直接访问。 - IanH
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接