1

I want to be able to successively write large arrays to a single binary file in Fortran. A simple example is below:

program TEST_IO


implicit none

!Define float precision
integer, parameter :: dp = selected_real_kind(33,4931)

!Define array dimensions
integer(kind=dp) :: nrows = 1d4, ncols = 12

!Define write/read arrays
real(kind=dp), dimension(:,:), allocatable :: ArrayWrite, ArrayRead


!Allocate
allocate(ArrayWrite(nrows,ncols))
allocate(ArrayRead(2*nrows,ncols))

!Populate the array
ArrayWrite=1.0_dp

!Write to file

open(unit=10, file='example.dat' , form='unformatted')
write(10) ArrayWrite
close(10)


!Re-populate array
ArrayWrite=2.0_dp

!And append to existing file
open(unit=10, file='example.dat', form='unformatted',position='append')
write(10) ArrayWrite
close(10)

!Now read in all the data

open(unit=10, file='example.dat' , form='unformatted')
read(10) ArrayRead
close(10)



end program TEST_IO

Since I have written an array of size (nrows,ncols) to file twice, I imagine the total write file to be of size (2*nrows,ncols). Indeed, from inspecting the output file size this seems to be true.

But when I try to read back in this data to ArrayRead, I simply get a runtime error: 'I/O past end of record on unformatted file'

Can anyone provide some guidance on where I am going wrong? Thanks.

user1887919
  • 829
  • 2
  • 9
  • 24
  • Your file has a record structure: trying to read twice as much from one record as exists, hoping that it'll have the same effect as reading from two records is not correct. There are other questions here addressing much the same topic, so I'll try to find a decent one to point to. – francescalus Aug 08 '19 at 09:26
  • 2
    The linked question first appears to be about MPI, but really the MPI part isn't too important. What you have here is doing much the same: writing out two records of data but then trying to read the same amount of data from one record. As noted in the answers to that other question, if you read first from one record then from the second you'll have joy, or you could switch to using stream access. Either way, you may want to use `position='rewind'` when opening the file to read to ensure the file is positioned at the start. – francescalus Aug 08 '19 at 09:34
  • 1
    @user1887919 just for info, be aware of how `ArrayRead` fills up with values if you only modify your code to open files using `access='stream'` (one of the suggestions in the linked answer) - the output of `print *, maxval(ArrayRead(:, 1:6)), minval(ArrayRead(:, 7:12))` may or may not be what you expect. – jbdv Aug 08 '19 at 09:55
  • Thanks both. Indeed, modyfying all open statements to include `access = 'stream' ` now allows me to read the array, but the read seems to be wrong? I would expect all rows of `1:nrows` to =1, and `nrows: 2*nrows`= 2, but the whole array just seems to be ones? – user1887919 Aug 08 '19 at 10:21
  • 3
    Fortran stores arrays in column-major order, i.e. when reading into `ArrayRead`, think of it as filling `2*nrows` values at a time into one column of the array, so that by the time you've read all the 1's from your first write, you've filled up columns `1:ncols/2` of `ArrayRead`, while the 2's from your second write will fill up columns `ncols/2+1:ncols`. – jbdv Aug 08 '19 at 10:52
  • Got it. Thanks both! – user1887919 Aug 08 '19 at 14:19

0 Answers0