14. File I/O

So far we have assumed that the input/output has been to the standard input or the standard output. It is also possible to read or write from files which are stored on some external storage device, typically a disk (hard disk, floppy) or a tape. In Fortran each file is associated with a unit number, an integer between 1 and 99. Some unit numbers are reserved: 5 is standard input, 6 is standard output.

Opening and closing a file

Before you can use a file you have to open it. The command is
    open (list-of-specifiers)
where the most common specifiers are:
    [UNIT=]  u
    IOSTAT=  ios
    ERR=     err
    FILE=    fname
    STATUS=  sta
    ACCESS=  acc
    FORM=    frm
    RECL=    rl
The unit number u is a number in the range 9-99 that denotes this file (the programmer may chose any number but he/she has to make sure it is unique).

ios is the I/O status identifier and should be an integer variable. Upon return, ios is zero if the stement was successful and returns a non-zero value otherwise.

err is a label which the program will jump to if there is an error.

fname is a character string denoting the file name.

sta is a character string that has to be either NEW, OLD or SCRATCH. It shows the prior status of the file. A scrath file is a file that is created and deleted when the file is closed (or the program ends).

acc must be either SEQUENTIAL or DIRECT. The default is SEQUENTIAL.

frm must be either FORMATTED or UNFORMATTED. The default is UNFORMATTED.

rl specifies the length of each record in a direct-acccess file.

For more details on these specifiers, see a good Fortran 77 book.

After a file has been opened, you can access it by read and write statements. When you are done with the file, it should be closed by the statement

      close ([UNIT=]u[,IOSTAT=ios,ERR=err,STATUS=sta])
where, as usual, the parameters in brackets are optional.

Read and write revisited

The only necessary change from our previous simplified read/write statements, is that the unit number must be specified. But frequently one wants to add more specifiers. Here is how:
      read ([UNIT=]u, [FMT=]fmt, IOSTAT=ios, ERR=err, END=s)
      write([UNIT=]u, [FMT=]fmt, IOSTAT=ios, ERR=err, END=s)
where most of the specifiers have been described above. The END=s specifier defines which statement label the program jumps to if it reaches end-of-file.

Example

You are given a data file with xyz coordinates for a bunch of points. The number of points is given on the first line. The file name of the data file is points.dat. The format for each coordinate is known to be F10.4. Here is a short program that reads the data into 3 arrays x,y,z:
      program inpdat
c
c  This program reads n points from a data file and stores them in 
c  3 arrays x, y, z.
c
      integer nmax, u
      parameter (nmax=1000, u=20)
      real x(nmax), y(nmax), z(nmax)

c  Open the data file
      open (u, FILE='points.dat', STATUS='OLD')

c  Read the number of points
      read(u,*) n
      if (n.GT.nmax) then
         write(*,*) 'Error: n = ', n, 'is larger than nmax =', nmax
         goto 9999
      endif

c  Loop over the data points
      do 10 i= 1, n
         read(u,100) x(i), y(i), z(i)
   10 enddo
  100 format (3(F10.4))

c  Close the file
      close (u)

c  Now we should process the data somehow...
c  (missing part)

 9999 stop
      end

Exercises

Exercise A
Change the example above such that the program writes a descriptive error message and stops if there is an error in the input data file.

Exercise B
Change the program from Exercise A such that it opens a new file norms.dat for writing and outputs the max-norm and 2-norm (Euclidean norm) of each data point (x,y,z). The first line should contain the number of points n, and thereafter each line should contain two floating point numbers, each printed in a field that is 12 characters wide. Test your program on this data file.


[Fortran Tutorial Home]
boman@sccm.stanford.edu