File Input/Output#
In Fortran files are managed by unit identifiers. Interaction with the filesystem
mainly happens through the open
and inquire
built-in procedures.
Generally, the workflow is to open a file to a unit identifier, read and/or write
to it and close it again.
integer :: io
open(newunit=io, file="log.txt")
! ...
close(io)
By default the file will be created if it is not existing already and opened for both reading and writing. Writing to an existing file will start in the first record (line) and therefore overwrite the file by default.
To create a read-only access to a file the status
and action
have to be
specified with
integer :: io
open(newunit=io, file="log.txt", status="old", action="read")
read(io, *) a, b
close(io)
In case the file is not present a runtime error will occur. To check for the existence
of a file prior to opening it the inquire
function can be used
logical :: exists
inquire(file="log.txt", exist=exists)
if (exists) then
! ...
end if
Alternatively, the open
procedure can return an optional iostat and iomsg:
integer :: io, stat
character(len=512) :: msg
open(newunit=io, file="log.txt", status="old", action="read", &
iostat=stat, iomsg=msg)
if (stat /= 0) then
print *, trim(msg)
end if
Note that iomsg requires a fixed-length character variable with sufficient storage size to hold the error message.
Similarly, writing to a file happens by using the status and action keyword. To create a new file use
integer :: io
open(newunit=io, file="log.txt", status="new", action="write")
write(io, *) a, b
close(io)
Alternatively, status="replace"
can be used to overwrite an existing file.
It is highly recommended to first check for the existence of a file before deciding
on the status to use.
To append to an output file the position keyword can be specified explicitly with
integer :: io
open(newunit=io, file="log.txt", position="append", &
& status="old", action="write")
write(io, *) size(v)
write(io, *) v(:)
close(io)
To reset the position in a file the built-in procedures rewind
and backspace
can be used. rewind
will reset to the first record (line), while backspace
will
return to the previous record (line).
Finally, to delete a file the file has to be opened and can be deleted after closing with
logical :: exists
integer :: io, stat
inquire(file="log.txt", exist=exists)
if (exists) then
open(file="log.txt", newunit=io, iostat=stat)
if (stat == 0) close(io, status="delete", iostat=stat)
end if
A useful IO feature is scratch files, which can be opened with status="scratch"
.
They are automatically deleted after closing the unit identifier.