From: Richard Maine on
lumbot <lumbot(a)gmail.com> wrote:

> The file was created by IDL into a binary in Mac Snow Leopard; I am
> reading the file on linux. Endian is the same.
> I don't think there is any first record indicating the number of
> bytes. There are 7*691201 records of 4 bytes --> 19353628 that is the
> file size.
> ----
> Somehow 'sequential' does not work.

That's because what you have is not a Fortran unformatted sequential
file. As others have noted, that is a particular form, which isn't what
you have.

> Maybe I am using F90 (not F2003)

Not pertinent to sequential or direct access. The only relevance to
f2003 is that f2003's stream access is really what you want. Many/most
f90/f95 compilers today do support the f2003 stream facility. I
recommend you pursue that. I don't recall exactly what compiler you are
using (GNU f90 isn't adequately descriptive, as Gordon mentioned). But I
believe that recent versions of both g95 and gFortran do support stream.

>
open(unit=2,file=fin,status='old',ACCESS='stream',FORM='UNFORMATTED',ios
tat=open_status)
> if(open_status>0)stop"unit2 open error"
> > ./mk_07orb_1sec
> STOP unit2 open error

Hmm. As Louis mentioned, taking the iostat out should give a better
message explaining what was wrong with the open. Assuming that the file
does exist and is readable (those assumptions are important; it is easy
to get lead astray on things like that) it might be that you are using
an old enough version of the compiler that it doesn't support stream.
The error message should make that evident, though.

> I tried to read in direct access mode
> integer(4)isec
> real(4)scpos15(3),scvel15(3)
>
>
open(unit=2,file=fin,status='old',ACCESS='direct',FORM='UNFORMATTED',ios
tat=open_status,recl=4)
> if(open_status>0)stop"unit2 open error"
> read(2,rec=1)isec
> read(2,rec=2)scpos15 (this is line 27)
> read(2,rec=5)scvel15
> the first record, isec, is now read correctly, but not the rest
> > ./mk_07orb_1sec
> At line 27 of file mk_07orb_1sec.f90
> Fortran runtime error: Short record on unformatted read

That's because you are trying to read 3 values (12 bytes) from the
second record. The rec=2 doesn't mean to start at the second record and
read as far as needed. It means to read just the second record. Some
compilers have non-portable hacks in this area, in particular, I think
some compilers special-case recl=1 to imply such behavior, but that's
not standard. That's one of the thinks that makes direct access a bit of
a pain for this purpose; doable, but sometimes painful.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: lumbot on
The system is linux and gfortran. Arjen Markus's clue worked. I tried
below and it works (as follows). There is 16B at the beginning. IDL
(interactive data language) does not create the head unless I use a
special flag. I think the case is closed.

character(100) fio
real(4) a(10),b(10)
integer(4) i

do i=1,10
a(i)=i
enddo

fio='./x.bin'
open(4,file=fio,status='replace',form='unformatted')
write(4)a
close(4)

open(2,file=fio,status='old',form='unformatted',access='sequential')
read(2)b
close(2)
write(*,*)b
From: robert.corbett on
On May 6, 11:15 pm, lumbot <lum...(a)gmail.com> wrote:
> I am getting the following error:
> Fortran runtime error: I/O past end of record on unformatted file
>
> The codes are:
> character(100)fin
> real(4)a
> fin='xx.bin'
>
> open(unit=2,file=fin,status='old',ACCESS='SEQUENTIAL',FORM='UNFORMATTED')
> read(2)a
> write(*,*)a
> close(2)
>
> The file exists>l xx.bin
>
> -rw-r--r-- 1 -- staff 19353628 May 5 14:01 ./xx.bin
>
> Any clue

The usual reason that error is given is that size of the data
being read exceeds the size of the record in the file. As
Arjen said, for most Fortran implementations on UNIX or Unix-like
operating systems, the length is in a four-byte header that
precedes the record. If the variable a is larger than the first
record in the file, then that is your problem.

Bob Corbett
From: Dave Allured on
lumbot wrote:
>
> Thanks everyone,
> The file was created by IDL into a binary in Mac Snow Leopard; I am
> reading the file on linux. Endian is the same.
> I don't think there is any first record indicating the number of
> bytes. There are 7*691201 records of 4 bytes --> 19353628 that is the
> file size.
> ----
> Somehow 'sequential' does not work. Maybe I am using F90 (not F2003)
>
> open(unit=2,file=fin,status='old',ACCESS='stream',FORM='UNFORMATTED',iostat=open_status)
> if(open_status>0)stop"unit2 open error"
> > ./mk_07orb_1sec
> STOP unit2 open error
> ----
> od -x xx.bin | head
> 0000000 0000 0000 4cee 45db d8c8 c3ee bcd3 441f
> 0000020 b7c8 3f1b 14b6 bf8e 0638 c0ed 0001 0000
> 0000040 51c3 45db 66d4 c3ef e2c1 441d aec5 3f19
> 0000060 02f3 bf8e 0c22 c0ed 0002 0000 5689 45db
> 0000100 f4ce c3ef 08a3 441c a5b1 3f17 f128 bf8d
> 0000120 11f9 c0ed 0003 0000 5b3e 45db 82b6 c3f0
> 0000140 2e79 441a 9c9d 3f15 df55 bf8d 17c0 c0ed
> 0000160 0004 0000 5fe2 45db 108d c3f1 5444 4418
> 0000200 9379 3f13 cd79 bf8d 1d73 c0ed 0005 0000
> 0000220 6477 45db 9e51 c3f1 7a03 4416 8a55 3f11

Others suggested reading this file with stream access. However I think
it was written by IDL specifically for direct access. It appears to be
direct access, little endian, record length 28 bytes, with the first
"word" of each record being a default 4-byte integer. I suppose the
other six "words" are default 4-byte reals, but I can't make out the
complete pattern for sure. Your sample code below reinforces this
guess.

You could also read the file as individual 4 byte "words", which is what
I think you are trying to do below. That is more confusing. That way,
you are doing more work keeping track of explicit word offsets for the
integer and six reals within each logical record. The errors you
encountered are a consequence of this. Better I think to make fortran
do that housekeeping for you, just read the file as 691201 logical
records of seven "words" each; one integer and six reals.

One caveat is that the units of "recl=" is not standardized. It may be
in bytes or 4-byte "words". IIRC it is bytes for gfortran on linux, but
I don't remember for sure. There may be a compiler line option to
change that.

> I tried to read in direct access mode
> integer(4)isec
> real(4)scpos15(3),scvel15(3)
>
> open(unit=2,file=fin,status='old',ACCESS='direct',FORM='UNFORMATTED',iostat=open_status,recl=4)
> if(open_status>0)stop"unit2 open error"
> read(2,rec=1)isec
> read(2,rec=2)scpos15 (this is line 27)
> read(2,rec=5)scvel15
> the first record, isec, is now read correctly, but not the rest
> > ./mk_07orb_1sec
> At line 27 of file mk_07orb_1sec.f90
> Fortran runtime error: Short record on unformatted read

Try the following, change recl from 28 to 7 if necessary (probably
not). Note that I made your variables to be default integers and
reals. This assumes the most likely scenario that your compiler uses
default 4-byte integers and reals. Explicit kind numbers e.g.
integer(4) are another can of worms for a different conversation.

integer isec
real scpos15(3), scvel15(3)
open(unit=2,file=fin,status='old',ACCESS='direct', &
iostat=open_status,recl=28)
if(open_status>0)stop"unit2 open error"
read (2,rec=1) isec, scpos15, scvel15

Subsequent record numbers go from 2 to 691201, incrementing by 1.

Stream access will also get the job done. Call it style, but I prefer
direct access for files that were constructed for that purpose in the
first place.

--Dave