Writing Files in Fortran

Here’s the translation of the Go code to Fortran, along with explanations in Markdown format suitable for Hugo:

Writing files in Fortran follows similar patterns to the ones we saw earlier for reading.

program writing_files
    use, intrinsic :: iso_fortran_env, only: error_unit
    implicit none
    
    character(len=*), parameter :: file1 = '/tmp/dat1'
    character(len=*), parameter :: file2 = '/tmp/dat2'
    integer :: unit1, unit2, iostat
    character(len=100) :: errmsg

    ! To start, here's how to dump a string into a file.
    open(newunit=unit1, file=file1, status='replace', action='write', iostat=iostat, iomsg=errmsg)
    if (iostat /= 0) call error_stop('Error opening file: ' // trim(errmsg))
    
    write(unit1, '(A)') 'hello'
    write(unit1, '(A)') 'fortran'
    close(unit1)

    ! For more granular writes, open a file for writing.
    open(newunit=unit2, file=file2, status='replace', action='write', iostat=iostat, iomsg=errmsg)
    if (iostat /= 0) call error_stop('Error opening file: ' // trim(errmsg))

    ! You can write character arrays as you'd expect.
    write(unit2, '(A)') 'some'

    ! A simple write statement is also available.
    write(unit2, '(A)') 'writes'

    ! Fortran performs buffered I/O by default, but you can force a flush to ensure all data is written.
    flush(unit2)

    ! Write another line
    write(unit2, '(A)') 'buffered'

    ! Close the file to ensure all data is written and resources are released.
    close(unit2)

    print *, 'File writing complete.'
end program writing_files

Let’s break down the Fortran code and explain the key concepts:

  1. We start by defining our program and importing necessary modules. The iso_fortran_env module provides access to environment-specific constants and procedures.

  2. We define the filenames as parameters and declare variables for file units, I/O status, and error messages.

  3. To write a simple string to a file, we use the open statement with status='replace' to create or overwrite the file, and action='write' to specify write-only access.

  4. We use write statements to output strings to the file. The format specifier '(A)' is used for character data.

  5. After writing, we close the file using the close statement.

  6. For more granular writes, we open another file in a similar manner.

  7. We can write character data directly using write statements.

  8. Fortran performs buffered I/O by default, but we can use the flush statement to ensure all data is written to the file immediately.

  9. Finally, we close the file to ensure all data is written and resources are released.

To run the file-writing code, compile and execute the Fortran program:

$ gfortran writing_files.f90 -o writing_files
$ ./writing_files
File writing complete.

Then check the contents of the written files:

$ cat /tmp/dat1
hello
fortran
$ cat /tmp/dat2
some
writes
buffered

In Fortran, file I/O is handled through unit numbers and the open, write, and close statements. While it doesn’t have a direct equivalent to Go’s bufio package, Fortran’s built-in I/O is typically buffered for efficiency. The flush statement can be used to ensure all data is written to the file.

Next, we’ll look at applying some of the file I/O ideas we’ve just seen to the standard input and output streams.