Our little note-taking app is simple and neat and does what it promised. However, one of the first issues we may run into is that if we specify an existing file to write our notes into, the program will overwrite the previous contents of the file with our new notes. The following listing shows an example of what that could look like.
Listing 6.9 Overwriting previous notes if writing to an existing file
./qn reminders.txt ❶
Call Jenny after work ❶
^C ❷
cat reminders.txt ❸
Call Jenny after work ❸
./qn reminders.txt ❹
Pick up groceries for tonight ❹
^C
cat reminders.txt ❺
Pick up groceries for tonight ❺
❶ Writes a reminder into a text file
❸ Prints the contents of the file to screen
❹ Now writes a new note into the same file
Oh no! The reminder to call Jenny is gone. What happened? Let’s take a look again at how we’re opening the file:
open(newunit=fileunit, file=trim(filename))
Without other keyword parameters specified, Fortran will default to opening a file at its beginning. If you write anything to it, the program will write from the beginning, and any contents that were already there will be overwritten. It doesn’t matter if you had a thousand lines of data and you’re writing only one line–the entire contents of the previous file will be gone.
What we really want our app to do is to keep writing to an existing file, continuing from the end and preserving existing notes:
./qn groceries.txt
Toast
^C
./qn groceries.txt
Avocadoes
^C
cat groceries.txt
Toast
Avocadoes
Fortunately, Fortran provides an easy way to open a file in the append mode, allowing you to continue where you left off:
open(newunit=fileunit, file=trim(filename), position='append')
Here, we added a third keyword parameter, position. It can take one of three values:
append–The file will be opened at its final position, preserving any previously written data.asis–The file will be opened “as is.” This is the default value if thepositionparameter is not specified and matters only if the file is already opened and preconnected to an I/O unit. (It must be the same unit!) In that case, the file will be opened at the same position. Otherwise, the file is opened at the beginning.rewind–The file will be opened at the beginning, without exception.
In general, if your app will always write from the beginning, whether to old or new files, you don’t have to specify position. Use position='append' only if you need to continue writing to an existing file, while preserving its original content. position= 'asis' and position='rewind' may only be useful in some special cases where you’re opening a file that’s already connected to an I/O unit and you need to change its position. Use this with caution, as rewinding the file and writing to it will truncate any existing content.
The position='append' setting in the open statement is convenient because it won’t change the behavior of writing to new files. If you’re appending to a new (empty) file, the result is the same as if you were writing from scratch. You can add this now to the open statement in listing 6.7. Does it work as expected? Great! The quick-note app is now more versatile, as it can add notes to existing files.
You can also rewind a file (set the read or write position to the start) at any time using the rewind statement:
rewind(fileunit)