Writing Files in Co-array Fortran

Here’s the translation of the Go code to Co-array Fortran, formatted in Markdown suitable for Hugo:

Our first example demonstrates how to write files in Co-array Fortran. Writing files follows similar patterns to reading files.

program writing_files
  use iso_fortran_env
  implicit none

  character(len=:), allocatable :: content
  integer :: unit, iostat
  character(len=100) :: errmsg

  ! Write a string to a file
  content = "hello" // new_line('a') // "fortran" // new_line('a')
  call write_file("/tmp/dat1", content)

  ! Open a file for writing
  open(newunit=unit, file="/tmp/dat2", status="replace", action="write", iostat=iostat, iomsg=errmsg)
  if (iostat /= 0) then
    print *, "Error opening file: ", trim(errmsg)
    stop
  end if

  ! Write byte values
  write(unit, '(5A1)', advance='no') char(115), char(111), char(109), char(101), new_line('a')
  print *, "Wrote 5 bytes"

  ! Write a string
  write(unit, '(A)') "writes"
  print *, "Wrote 6 bytes"

  ! Flush the buffer
  flush(unit)

  ! Use a buffered write
  write(unit, '(A)') "buffered"
  print *, "Wrote 8 bytes"

  ! Close the file
  close(unit)

contains

  subroutine write_file(filename, content)
    character(len=*), intent(in) :: filename, content
    integer :: unit, iostat
    character(len=100) :: errmsg

    open(newunit=unit, file=filename, status="replace", action="write", iostat=iostat, iomsg=errmsg)
    if (iostat /= 0) then
      print *, "Error opening file: ", trim(errmsg)
      return
    end if

    write(unit, '(A)', iostat=iostat, iomsg=errmsg) content
    if (iostat /= 0) then
      print *, "Error writing to file: ", trim(errmsg)
    end if

    close(unit)
  end subroutine write_file

end program writing_files

This program demonstrates various ways to write files in Co-array Fortran:

  1. We start by writing a string directly to a file using a custom subroutine write_file.

  2. Then, we open a file for more granular writes. In Fortran, it’s common to use the open statement with newunit to get a new unit number automatically.

  3. We write byte values to the file using the char function to convert integers to characters.

  4. We demonstrate writing a string directly to the file.

  5. The flush statement is used to ensure all buffered data is written to the file.

  6. Finally, we show another string write, which could be considered a “buffered” write in the context of Fortran’s I/O system.

  7. We close the file explicitly at the end.

To run this program:

$ gfortran -o writing_files writing_files.f90
$ ./writing_files
Wrote 5 bytes
Wrote 6 bytes
Wrote 8 bytes

Then check the contents of the written files:

$ cat /tmp/dat1
hello
fortran

$ cat /tmp/dat2
some
writes
buffered

Note that Co-array Fortran doesn’t have a direct equivalent to Go’s bufio package for buffered I/O. Fortran’s I/O system handles buffering internally, and the flush statement can be used to ensure data is written to the file.

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