如何跳过Fortran无格式文件中的数组?

时间:2014-06-20 14:53:10

标签: io fortran binaryfiles

我的程序在Fortran中读取“未格式化”的文件。除此之外,这个文件包含一个我的程序不需要的数组,但是它可以变得非常大。我想跳过这个数组。

如果这是编写数据的程序:

program write
  real :: useless(10), useful=42

  open(123, file='foo', form='unformatted')
  write(123) size(useless)
  write(123) useless
  write(123) useful
end program write

然后这适用于阅读:

program read
  integer :: n
  real, allocatable :: useless(:)
  real :: useful

  open(123, file='foo', form='unformatted')
  read(123) n
  allocate(useless(n))
  read(123) useless
  read(123) useful

  print*, useful
end program read

但我想避免分配“无用”数组。我发现了这个

program read2
  integer :: n, i
  real :: useless
  real :: useful

  open(123, file='foo', form='unformatted')
  read(123) n
  do i=1,n
     read(123) useless
  end do
  read(123) useful

  print*, useful
end program read2

不起作用(因为记录长度被写入文件 [编辑,请参阅francescalus'回答])。

不能选择更改文件的格式。

2 个答案:

答案 0 :(得分:5)

读取比记录中文件存储单元更少的文件存储单元并不是一件容易的事。

program read
  real :: useful

  open(123, file='foo', form='unformatted')
  read(123)
  read(123)
  read(123) useful

  print*, useful
end program read

每个"空" read仍会提前连接文件的记录以进行顺序访问。

作为进一步的评论:第二次尝试不会失败"因为记录长度"。由于尝试读取单独的记录,它失败了。这种差异的重要性的例子可以在许多SO帖子中找到。

答案 1 :(得分:1)

Francescalus已经展示了如何跳过整条线。如果一行包含一些应该被跳过的数据以及一些要读取的数据,则可以重复读取一个虚拟变量以跳过坏数据。以下是一个证明这一点的程序。

program write
real :: dummy,useless(10), useful=42
integer, parameter :: outu = 20, inu = 21
character (len=*), parameter :: fname = "foo"
integer :: n
call random_seed()
call random_number(useless)
open(outu, file=fname, form='unformatted', action = "write")
write(outu) size(useless)
write(outu) useless
write(outu) useful
close(outu)
open(inu, file=fname, form='unformatted', action = "read")
read (inu) n
read (inu) (dummy,i=1,n)
read (inu) useful
write (*,*) "useful = ",useful
end program write