xebtl
xebtl

Reputation: 490

How to skip over an array in a Fortran unformatted file?

My program reads an “unformatted” file in Fortran. Among other things, this file contains an array that my program does not need, but which can get quite large. I would like to skip this array.

If this is the program writing the data:

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

Then this works for reading:

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

But I would like to avoid allocating the “useless” array. I discovered this

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

does not work (because of the record lengths being written to the file [EDIT, see francescalus' answer]).

It is not an option to change the format of the file.

Upvotes: 2

Views: 970

Answers (2)

Fortranner
Fortranner

Reputation: 2605

Francescalus has shown how to skip over an entire line. If a line contains some data that should be skipped over as well some data to be read, you can read a dummy variable repeatedly to skip the bad data. Below is a program demonstrating this.

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

Upvotes: 1

francescalus
francescalus

Reputation: 32366

It isn't a sin to read fewer file storage units than are in the record.

program read
  real :: useful

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

  print*, useful
end program read

Each "empty" read still advances the record for a file connected for sequential access.

As a further comment: the second attempt doesn't fail "because of the record lengths". It fails because of the attempt to read separate records. Examples of the significance of this difference can be found in many SO posts.

Upvotes: 7

Related Questions