如何在未知相应的RECL时使用Fortran未格式化的直接访问来访问单个记录?

时间:2017-05-10 17:02:42

标签: fortran file-access

除非使用F2003中提供的new-ish流访问,否则Fortran会将文件视为一系列记录。如果连接文件以进行直接访问,则可以通过指定记录号以任何顺序访问任何记录。例如:

open(newunit=funit, file=filename, form='unformatted', access='direct', &
     recl=64, status='old')
read(funit, rec=2) data
close(funit)

所以这听起来很棒......但是,我不确定我是否理解RECL参数以及如果没有正确的记录长度,如何有效地使用直接访问。从文档(各种英特尔Fortran版本):

  

所有记录都具有OPEN语句中RECL选项指定的长度。

换句话说,直接访问允许以等于或小于RECL的数量访问数据,同时以RECL 的增量移动文件。也就是说,您可以指定任何您喜欢的值(等于或小于文件的大小,我假设)。我觉得后见之明显而易见......但我希望在某种程度上可以发现适当的RECL。 1 也许我做错了,但我想从指定的记录中获取数据 - 不多也不少。

除了在'标题中编码相应的RECL值之外'文件的一部分,如果事先不知道正确的记录长度,有没有办法一次访问一个文件连接文件未格式化(甚至格式化)直接访问?用什么技巧来做这件事?

1 我曾希望inquire(funit, recl=rl)提供适当的RECL,但如果文件已连接进行直接访问,则会返回文件打开时指定的RECL值。如果连接为顺序访问,它似乎返回允许的最大记录长度(?),在我的情况下为2040。

1 个答案:

答案 0 :(得分:2)

实际上,不可能通过查看文件找到它,因为这只是数据和(通常)没有记录标记,因此编译器只看到非结构化字节流。至少在面向字节的计算机中。我对面向记录的文件系统一无所知,只知道它们存在。

如果您知道直接访问记录中存储了哪种数据,您可以询问编译器,不要询问文件,而是询问数据。

例如,如果记录由变量abc组成,无论它们是什么,

 !just an example
 real :: a(10)
 type(my_type) :: b
 character(5) :: c(3)

你问这样的记录有多大

 inquire(iolength=rl) a, b, c

然后将文件与recl=rl

相关联
open(newunit=funit, file=filename, form='unformatted', access='direct', &
     recl=rl, status='old')

例如,请参阅Why direct access I/O works incorrectly with Intel Visual Fortran

请注意,RECL值不可移植, 会因编译器而异。有些用字节测量,有些用4字节字测量。我只记得gfortran和ifort不同,而不是哪一个。我不在乎哪一个是哪个。

如果您发现自己使用魔术常量指定RECL,就像在recl=64中做错了一样,因为这在其他编译器中不起作用。你应该总是有一个变量,而不是一个固定的数字。