From: Richard Maine on 7 May 2010 12:27 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 7 May 2010 13:00 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 7 May 2010 22:06 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 10 May 2010 12:43
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 |