Hi folks, I’ve been trying to mimic Fortran’s read method concerning a sliced array that was before saved, and then read without any issue in the slice of an array :
(whole fortran reader code is available here: https://github.com/florentrenaud/rdramses)
if(hydro) open(3, file='rdr_'//TRIM(nchar)//TRIM(out)//'.hydro')
!!
!! Many other instructions
!!
read(2) var(:,index1, index2)
Say that the record i’m reading here is bigger than the allocated size for the var variable, how would fortran behave in this case ? I used to believe It would crash, but the only code crashing is the one I wrote… Thanks to whoever may provide me some guidance. have a good day!
For a normal unformatted file, the read statement reads the first elements from the record into the array slice, and then skips to the end of the record to prepare for the next read statement. That is why unformatted records have the extra header and trailer info to allow skipping forward (in this case) or backward (with backspace) over the records. This is the way unformatted i/o has always worked in fortran, even before f77 (although not with the slice notation, just with arrays or implied do loops).
However, if it is a stream file, with no record structure, then I think the array slice is read and the file is left positioned after the last location that was input. You do not show the open statement for unit 2, so the expected behavior cannot be determined.
With stream files (access = ‘stream’) the read or write position is indeed left at the position immediately after the last byte that was read or written. That is the whole purpose in fact of such files.
So, if you want to make sure you skip the parts that were not read, then you need to read them as dummy or you need to reposition the file pointer, via:
read(2, pos = some-position-in-bytes) data
Note: you may need to be careful about the actual unit in which the position is measured - iso_fortran_env contains a parameter for this - file_storage_size.
Hi Ron!
You lift a huge weight of my shoulders.
I thought I understood it, but I clearly was out of it. If i get it right (in the case of unformatted file reading), read instruction will read the whole record anyway and put as much data from the record as it can in the given destination variable (in the case of the array slice, it’ll be in the dedicated column). Is that it ?
Thanks for your insights.
Best regards ,
Hi Arjen !
Actually, I made the wrong copy paste while redacting my question. The intended file was well openned in the 2nd unit. Also, it’s openned with form=“unformatted”. Ron’s answer gave me some good insights, but I really wanted to thank you for taking time to try to help me.
Have a good day!
As a general rule, assigned unit numbers should not be small integers in fortran. Small means less than 7 or less than 10 or something like that. The reason is that fortran allows special units to be preconnected. Historically these preconnected units were line printers, tape drives, card readers, card punchers, and things like that. In more modern times, the preconnected units include standard in, standard out, and standard error. Once a programmer overrides one of these preconnections with a small unit number, then it does not revert back to that preconnected unit after it is closed, and the subsequent i/o to that unit no longer behaves as it did before the open/close sequence. Unit 2 in particular is often preconnected to standard output or to standard error. The usual recommendation is to use units larger than 10 or to use the newunit= keyword of the open statement in order to safely avoid such conflicts.
Glad to learn that. I’m porting the code from the mentioned git repo to c++. Reminds me of the precautions you should take when choosing a port for network applications.
Should i issue this on the original fortran code ?
while coding, i just had another question raising in my mind. Say that the record is smaller than the target array. We’ll just read the record as a whole, store as much data from the record to the target array as we can, and leave the other cells untouched, right ?