在 Fortran 90 中从文件末尾读取

Read from end of file in Fortran 90

我的问题是如何从文本文件的末尾开始阅读。 例如,

do
  read(1,*) i
  print *,i
end do

将读取文件 1 中的每一行,并将内容打印到终端。我如何从文件末尾开始执行此操作?

这是不可能的。阅读总是从某一点开始,并向前推进。默认情况下,它从第一个字节开始;但你可以跳转到其他位置。

关键问题是,在自由格式文件中,除非您阅读文件,否则无法知道行从何处开始。你可以跳到最后一个字节,检查它是否是行分隔符,如果不是,则跳到它之前的字节,爬回直到找到换行符,但效率很低。

更好的方法是读取整个文件一次,记住换行符的位置;然后向后迭代这个数组,跳转到每一行的开始位置来读取它。这不是那么低效,但也不是很好。

如果您有足够的内存,最好的方法是将整个文件读入一个行数组,然后在内存中反转数组。

您可以通过在读取语句中使用 inquireaccess=streampos 标记来实现您想要的。 10 分钟的快速练习给出以下结果。

program foo
   implicit none
   integer fd, i, j, m, n
   character, allocatable :: s(:)
   character :: c
   open(newunit=fd,file='foo.f90',access='stream',status='old', &
   position='append')
   inquire(fd, pos=n)
   allocate(s(n))
   m = 1
   do i = n-1, 1, -1
      read(fd, pos=i) c
      s(m:m) = c
      if (iachar(c) == 10) then
         do j = m, 1, -1
            write(*,'(A1)',advance='no') s(j)
         end do
         m = 1
      else
         m = m + 1
      end if
   end do
   write(*,*)
   do j = m-1, 1, -1
      write(*,'(A1)',advance='no') s(j)
   end do
   write(*,*)
   close(fd)
end program foo

将其保存到名为 foo.f90 的文件中,编译,然后 运行。这里有人可以让它更优雅。编辑后的原始版本:不需要为 s(j).

使用数组部分