Back to index.html.
File input and output
In Fortran, input and output (I/O) from/to a file has the same form as I/O from the keyboard or to the screen (physical devices). The only difference is that, for the file I/O, the source and the destination are a file, not the physical devices. Defining a file as a “device” allows you to read and write the data to and from the “device” using the
write statements with the same edit descriptors as we have seen before. Before trying the file I/O, I encourage the readers to master the basics of
read with edit descripter.
In this chapter, we will see how to write and read a file.
Output to text file
The following is a typical program to save some numbers to a file. This program creates a file
output.txt in the current directory.
program file implicit none real :: a,b,c ! computation a = 1 b = 2 c = log(a+b) ! save the values to a file open(10,file='input.txt') write(10,*) a,b,c close(10) end program file
- Use the
openstatement to connect a file name
output.txtto an integer number (logical unit number). After this, all the access to the file is performed through this number.
- Writes 3 values to ten files using the default format.
- After the values are written, disconnect to the file using
You can check if the new file is created in the current directory where you are working. It is a text file containing human-readable characters, and it contains 3 numbers with the default format as you get by
print *,a,b,c, on the screen. To short, the output to a text file is the same as the screen output except for that additional statements,
close, are needed.
Input from text file
File reading has the same behavior as keyboard input except that the values are from a file. As file writing, you have to call
open before reading a file, and
close for the termination. Using the file created above, you can read 3 values from the file.
program file implicit none real :: a,b,c ! read the values from a file open(10,file='output.txt') read(10,*) a,b,c close(10) end program file
output.txt should be in the same directory as the program. Otherwise, this program stops on
open with an error. The
read statement has at least two parameters in
() with the same meaning as
write. If enough values are not in the file, the
read statement generates an error.
You can use any unit number (basically, positive integer numbers) if it has not been already used as the unit number. A best practice is to use an integer variable for the unit number. See the following piece of code.
program file ... integer :: unit ... unit = 10 open(unit,file='output.txt') write(unit,*) a,b,c close(unit) end program file
In the Modern Fortran standard, the user does not have to choose the unit number anymore. The system can automatically assign an appropriate number through the
newunit= option in
open. The above example is reduced to the following code.
program file ... integer :: unit ... open(newunit=unit,file='output.txt') write(unit,*) a,b,c close(unit) end program file
You don’t have to initialize
unit because a value is assigned to
unit at the
Practical text file reading and writing
Reading a file
Opening an exisitng file
If you want to make sure that a file exists when opening the file, you can put an option,
If there is no file, the program stops with an error. You can get the error status of
iostat= with an arbitrary integer variable.
integer :: info ... open(newunit=unit,file="input.txt",status="old",iostat=info)
With the above statement, the program checks if there is
input.txt or not. If the file is not there, it returns a negative value to the variable (
info). Otherwise, it returns 0 to the variable. So, the following code catches the error.
integer :: info ... open(newunit=unit,file="input.txt",status="old",iostat=info) if(info/=0) stop "No file"
status="old", make the file read-only. When you try
write to this file, you should get an error.
Error status while reading the file
A text file may have multiple lines (rows), and sometimes you do not know how many rows the file has. The
read statement can detect an error while reading a text file. The error status is available with the
iostat= option with an arbitrary integer variable. Here is a piece of code with an arbitrary variable,
info, to catch the error status.
integer :: unit,info ... read(unit,*,iostat=info) a,b,c
In the above code,
info has the status of
infois 0 when there is no error.
infois negative if there is no more data in the file.
infois positive if there are some errors (e.g., the data in the file does not match the variables).
Repeated reading the data
There is a typical form to read the data from the file until the end of the file. It looks similar to read the data from the keyboard until you input particular values.
do read(unit,*,iostat=info) a,b,c if(info<0) exit ... end do
When a line has space-separated, multiple fields, but the variables cannot read all of them, and the
read statement ignores the rest of them. For example, you have the following file.
10 10 15 ABC
The following code reads the first 3 numbers but ignores the characters
ABC without any errors.
In this way, while you read some numerical values in the first few fields, you can put characters in the last fields.
Writing a file
Creating a new file
When you open a file that already exists, the
write statement will renew it by default. Precisely, it completely removes the existing file, and the new content is placed in the file as the first record. Be aware that there is a risk to lose the file. The following piece of code shows this behavior.
open(newunit=unit,file="data.txt") ! It removes the file, and it updates the file by the value, 100. write(unit,*) 100
Appending data to an existing file
IF a file is already there, you can append the data to it without losing the file. You need
open to do this.
Using this option, the new data is added to the end of file.
Error status while reading the file
With this option, the new data is added to the end of the file.
integer :: unit,info ... write(unit,*,iostat=info) a,b,c
The status (
info) is 0 when there is no error. It is positive if there is an error with
write (for example, trying to write a file in a read-only device).
No “new line”
write statement puts a “newline” at the end of the data. To suppress the new line, use
advance="no". It is useful in a file and on the screen.
write(unit,*,advance="no") 10,20 write(unit,*,advance="no") 30,40 write(unit,*) 50
10 20 30 40 50
Moving a file position
When open a file, the file position is set to the beginning of the file by default. With
open, the file position is at the end of the file. Whenever you perform
write, the file position moves to the top of the next line. There are some statements to change the file position.
||Move back to the previous line||
||Move back to the beginning of the file||
When to lose the file
There is an essential fact in the file I/O: you can perform both
write to the same file by default. This fact explains when you lose a file by
write. Assume that you move the position to the top of the third line in a text file by performing
read twice. The file position is shown as
> in the following example file.
The first line The second line > The third line The fourth line
With this setting, when you perform
write, the program removes all the subsequent lines at and after the third line in the file, then it writes a new line to the third line. Here is the resulting content in the file.
The first line The second line Added line >
When opening a file, the file position is at the top of the file; you write the data to the file, and you will lose the existing content in the file. When opening it with
position=append, the position moves to the end of the file, and you can write the new line while keeping the entire file. I encourage the reader not to use both
write in the same file unless you really need to do it.
Back to index.html.