On Saturday, October 27, 2018 at 8:22:54 PM UTC-4, Steve Lionel wrote:
> ..
> I suggested an alternate approach, where one opens the file initially
> with 'APPEND' rather than 'REWIND', uses INQUIRE to get the current
> position, REWIND, write the initial records and then do a WRITE with
> POS= the saved position (and no I/O list). This is standard-conforming
> and accomplishes what he asked for. (Except that Gary doesn't like this
> solution for reasons not yet explained.)
> ..
The advantage of "STREAM IO" is that one can easily perform data transfer in almost any order.
Given this facility, why bother to open with 'APPEND' to save the position, then 'REWIND' to write some initial data followed by transfer of the extra data starting at the saved position plus 1?
OP writes on the Intel forum, "I was attempting to first open in the rewind position and overwrite a time stamp, then simply reposition to the end and begin appending records."
So why not just open with 'APPEND', write the extra data, then transfer the updated initial data (say time stamp) at initial position which is simply 1? See below where subprogram FPRINT mimics OP's stated desire. The code works fine with both Intel Fortran as well as gfortran:
--- begin example ---
program p
use, intrinsic :: iso_fortran_env, only : compiler_version, iostat_end, iostat_eor
implicit none
character(len=*), parameter :: fname = "C:\temp\tmp.dat"
character(len=*), parameter :: msg = " Hello World! "
character(len=8) :: sdate
character(len=10) :: stime
print *, "Compiler Version: ", compiler_version()
call date_and_time( sdate, stime )
call iprint()
call rfile()
call fprint()
call rfile()
stop
contains
subroutine iprint()
integer :: lun
open( newunit=lun, file=fname, access="stream", form="unformatted", status="replace" )
write( lun ) sdate, stime, msg
close( lun )
return
end subroutine
subroutine fprint()
integer :: lun
integer :: istat
character(len=2048) :: imsg
character(len=8) :: ldate
character(len=10) :: ltime
character(len=*), parameter :: emsg = "I'm glad Fortran introduced stream access!"
! Open with position="append"
open( newunit=lun, file=fname, access="stream", form="unformatted", status="old", &
position="append", iostat=istat, iomsg=imsg )
if ( istat /= 0 ) then
print *, "fprint: open failed - iostat=", istat
print *, trim(imsg)
stop
end if
write( lun ) emsg ! write extra data
call date_and_time( ldate, ltime )
write( lun, pos=1 ) ldate, ltime ! update time stamp at beginning of file
close( lun )
return
end subroutine
subroutine rfile()
integer :: lun
integer :: istat
integer :: i
integer, parameter :: iostat_zero = 0
character(len=2048) :: imsg
open( newunit=lun, file=fname, access="stream", form="unformatted", status="old", &
position="rewind", iostat=istat, iomsg=imsg )
if ( istat /= 0 ) then
print *, "fprint: open failed - iostat=", istat
print *, trim(imsg)
stop
end if
i = 0
imsg = ""
loop_read: do
i = i + 1
if ( i > len(imsg) ) then
print *, "File content exceeds buffer, read aborted."
exit loop_read
end if
read( lun, pos=i, iostat=istat ) imsg(i:i)
select case ( istat )
case ( iostat_zero )
! continue reading
case ( iostat_end, iostat_eor )
exit loop_read
case default
print *, "Error reading file at position ", i
stop
end select
end do loop_read
close( lun )
print *, "Contents of ", trim(fname), ":"
print *, trim(imsg)
return
end subroutine
end program p
--- end example ---
Upon execution with gfortran:
Compiler Version: GCC version 9.0.0 20181014 (experimental)
Contents of C:\temp\tmp.dat:
20181027231708.121 Hello World!
Contents of C:\temp\tmp.dat:
20181027231708.128 Hello World! I'm glad Fortran introduced stream access!
Upon execution with Intel Fortran:
Compiler Version:
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.0.117 Build 20180804
Contents of C:\temp\tmp.dat:
20181027231735.491 Hello World!
Contents of C:\temp\tmp.dat:
20181027231735.499 Hello World! I'm glad Fortran introduced stream access!