File Input/Output
Sequential unformatted files include record markers (compiler-specific); access="stream" gives a plain byte stream readable from C/Python (numpy.fromfile).
18.1 OPEN, WRITE, READ, CLOSE
program file_io
implicit none
integer :: u, ios, i
real :: x, y
character(len=256) :: line, msg
! Write a text file
open(newunit=u, file="data.txt", status="replace", action="write", iostat=ios, iomsg=msg)
if (ios /= 0) error stop trim(msg)
do i = 1, 5
write(u, '(i3, 2f10.4)') i, real(i), sqrt(real(i))
end do
close(u)
! Read it back until end of file
open(newunit=u, file="data.txt", status="old", action="read")
do
read(u, *, iostat=ios) i, x, y
if (ios /= 0) exit ! iostat_end (negative) at EOF
print *, i, x, y
end do
close(u)
! Read whole lines
open(newunit=u, file="data.txt", action="read")
do
read(u, '(a)', iostat=ios) line
if (is_iostat_end(ios)) exit
print *, trim(line)
end do
close(u)
end program file_io18.2 OPEN specifiers
let the runtime choose a free unit number (F2008) "old", "new", "replace", "scratch", "unknown" "read", "write", "readwrite" "asis", "rewind", "append" "sequential", "direct", "stream" "formatted", "unformatted" record length (direct access) iostat=, iomsg=
18.3 Unformatted (binary) & stream I/O
Sequential unformatted files include record markers (compiler-specific); access="stream" gives a plain byte stream readable from C/Python (numpy.fromfile).
real(dp) :: big(1000, 1000)
open(newunit=u, file="matrix.bin", form="unformatted", access="stream", status="replace")
write(u) shape(big), big ! raw bytes, fast and compact
close(u)
open(newunit=u, file="matrix.bin", form="unformatted", access="stream", status="old")
read(u) dims, big
close(u)18.4 Direct access
open(newunit=u, file="records.dat", access="direct", recl=8, form="unformatted")
write(u, rec=5) 3.14_dp
read(u, rec=5) x18.5 Other I/O statements
inquire(file="data.txt", exist=exists, size=nbytes)
inquire(unit=u, opened=is_open, name=fname)
inquire(iolength=reclen) x, y ! record length for direct access
rewind(u); backspace(u); endfile(u); flush(u)
write(*, '(a)', advance='no') "Prompt> " ! non-advancing I/O18.6 NAMELIST — simple configuration files
integer :: nsteps = 100
real :: dt = 0.01
character(len=20) :: method = "euler"
namelist /config/ nsteps, dt, method
open(newunit=u, file="input.nml", status="old")
read(u, nml=config)
close(u)
write(*, nml=config)&config
nsteps = 500
dt = 0.001
method = "rk4"
/18.7 Asynchronous I/O
open(..., asynchronous="yes"), write(u, asynchronous="yes", id=req) data, wait(u, id=req) — overlap I/O with computation.
18.8 Scientific file formats
For large/portable datasets use NetCDF (netcdf-fortran), HDF5 (Fortran API), ADIOS2, or JSON/TOML via json-fortran, toml-f.