File io 在Fortran 90中从文件末尾读取

File io 在Fortran 90中从文件末尾读取,file-io,fortran,File Io,Fortran,我的问题是如何从文本文件的末尾开始读取。 比如说, do read(1,*) i print *,i end do 将读取文件1中的每一行,并将内容打印到终端。如何从文件末尾开始执行此操作?这是不可能的。阅读总是从某一点开始,然后继续前进。默认情况下,它从第一个字节开始;但是你可以跳到其他地方 关键问题是,在自由格式文件中,除非读取文件,否则无法知道行的起始位置。您可以跳转到最后一个字节,检查它是否是行分隔符,如果不是,则跳转到它前面的字节,向后爬行直到找到新行,但这将非常低效 更好的

我的问题是如何从文本文件的末尾开始读取。 比如说,

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

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

这是不可能的。阅读总是从某一点开始,然后继续前进。默认情况下,它从第一个字节开始;但是你可以跳到其他地方

关键问题是,在自由格式文件中,除非读取文件,否则无法知道行的起始位置。您可以跳转到最后一个字节,检查它是否是行分隔符,如果不是,则跳转到它前面的字节,向后爬行直到找到新行,但这将非常低效

更好的方法是把整个文件读一遍,记住换行符在哪里;然后向后迭代这个数组,跳到每行的起始位置读取它。这不是效率低下,但也不是很好


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

您可以通过使用
inquire
access=stream
和read语句中的
pos
标记来实现所需。一个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)

确定使用数组节。谢谢你的回复。我怎么跳到某一行?假设我正在一行一行地搜索文件中的某个特定数字,但我知道它在前500000行之后的某个地方。正如我刚才解释的,如果不从一开始读取所有行来计算换行符,你就不能。这就像是告诉某人蒙着眼睛开车时左转第五条街——你可以通过知道一个城市街区的平均长度来估算,但你转弯时更可能撞到一栋建筑物,而不是以同样的方式撞到你想要的那条街,您可以说,如果您知道平均行长度为5字节,则第500000行可能从第2500000字节左右开始-但这不能保证。Ok。我现在明白了。当然,从文件的结尾到第一个字符都可以读取。一个简单的解决方案包括
access=stream
backspace