Fortran 我可以将文件指针移动到格式化文件中的特定(字节)位置吗?

Fortran 我可以将文件指针移动到格式化文件中的特定(字节)位置吗?,fortran,Fortran,我正在读一个格式化的ascii文件。该文件基本上是ascii编码的,如下所示: fieldname 1 header info 1 header info 2 header info 3 aruieopaurjjk&*(^0uio3789$ #$adsfhoueraeiknvaer93-8(&897klfaicvnjai9ea890 34 *(()kla3j90ajkl4a8 ... fieldname 2 header info 1 header info 2 header

我正在读一个格式化的ascii文件。该文件基本上是ascii编码的,如下所示:

fieldname 1
header info 1
header info 2
header info 3
aruieopaurjjk&*(^0uio3789$
#$adsfhoueraeiknvaer93-8(&897klfaicvnjai9ea890 34
*(()kla3j90ajkl4a8 ...

fieldname 2
header info 1
header info 2
header info 3
8&80973jknaua890a3a()Ujkl;fjaoi0()8&*(&jla;f)*(
jkl;aje()()78907jkoja0988093jn890&*(4fakoa343a
...
因此,虽然文件是ascii码,但它们不是人类可读的。记录长度不一致。假设文件指针位于
fieldname
的正前方,我有读取数据的例程。它检查以确保字段名是我想要的,并读取/解码返回数据的字段。如果该字段不是我想要的字段,它将读取行,直到到达
fieldname
行。正如你所能想象的,这是非常低效的。要读取最后一个字段,我基本上需要按顺序读取其他每个字段。另外,如果我读错了,我需要倒带整个文件,然后重新开始。我想做的是创建一个索引,这样我就可以将字段名映射到文件开头的字节偏移量。这样,我就可以“查找”到文件中的正确位置,并继续作为格式化的顺序文件进行读取

我对任何允许我以以下方式读取文件的解决方案感到满意:

read(iu,'(A)',end=190) mystring  !get from current position to end of line
read(iu,*,end=190) myint1,myint2 !read two integers
read(iu,'(a,i8,3e14.7,i8,a)',end=190, err=900) !read a string, 8 character wide integer ...
我甚至可以使用一个具有某种优化的
getline
函数和流访问的解决方案。然后我可以用调用getline,然后读取返回的字符串来替换上面的内容

我已经看过了,但是我的问题稍微有点笼统(那篇文章想要一个行号,我想要一个字节偏移量)。这似乎可以通过使用流访问和pos说明符来实现,但我不确定这是否会迫使我完全重写读卡器(这几乎是不可能的,因为我不知道读卡器实际上如何将看似随机的字符串转换为浮点数)。

格式化流访问(在Fortran 2003标准中引入)允许您查找以前读取过的文件中的某个位置。由于格式化流仍然采用基于记录的方法(正式使用换行符作为记录分隔符),因此通常可以重用格式化顺序访问所用的相同代码

您可以使用INQUIRE语句获取当前文件位置:

INTEGER :: file_pos
INQUIRE(UNIT=iu, POS=file_pos)
在读取包含每个
字段名
行的记录之前,您可以以这种方式调用INQUIRE,然后读取该记录,确定该记录的字段名,并将字段名和文件位置存储在数组或类似数组中,以供以后查找

您可以使用非前进读取重新定位到以前存储的位置:

READ (iu,"()", ADVANCE='NO', POS=file_pos)
随后的READ语句将继续执行,就像第一次遇到重新定位记录的顺序格式化文件一样。

格式化流访问(在Fortran 2003标准中引入)允许您查找文件中以前读取过的位置。由于格式化流仍采用基于记录的方法(正式使用换行符作为记录分隔符),因此通常可以重用用于格式化顺序访问的相同代码

您可以使用INQUIRE语句获取当前文件位置:

INTEGER :: file_pos
INQUIRE(UNIT=iu, POS=file_pos)
在读取包含每个
字段名
行的记录之前,您可以以这种方式调用INQUIRE,然后读取该记录,确定该记录的字段名,并将字段名和文件位置存储在数组或类似数组中,以供以后查找

您可以使用非前进读取重新定位到以前存储的位置:

READ (iu,"()", ADVANCE='NO', POS=file_pos)

随后的READ语句将继续执行,就像第一次遇到重新定位记录的顺序格式化文件一样。

Brilliant。我将对此进行测试。您知道现在常见的编译器是否广泛支持此功能吗?(gfortran、pgf90、ifort等)最近的iPort支持它-我知道12.0早期版本中的一些错误已经修复。最近(6月份的版本)的gPortran似乎有一些支持,但存在一些错误。非常棒。我将对此进行测试。你知道这项功能现在是否得到了普通编译器的广泛支持?(gPortran,pgf90,iPort,…)最近的iPort支持它-我知道12.0早期版本中的一些bug已经修复。最近(6月版本)的gfortran似乎有一些支持,但存在一些bug。