brian@radio.astro.utoronto.ca (Brian Glendenning) (05/31/89)
I have a problem where I want to do direct unformatted i/o to a file, where the record length isn't known until run-time, but a maximum length is known. So I do something like: PARAMETER (BIG=1024) REAL LINE(BIG) READ (5,*) NSIZE OPEN ( [...] ACCESS='DIRECT', FORM='UNFORMATTED', RECL=NSIZE*4, [...]) (4 is a constant that varies with hardware) Now obviously I want to put NSIZE reals into LINE and write them out later. My question is: what is the proper way to do this. On our Sun 3 it looks like you fill up the last NSIZE elements of LINE and use a write statement of the form: WRITE( [...] REC=[...]) LINE(BIG-NSIZE+1) Is this the right thing to do in general? My recollection was that you filled up the first NSIZE elements of LINE, and used a line like: WRITE( [...] REC=[...]) LINE and the fortran io would automatically take the appropriate number of units of storage (RECL) from the beginning of line. However, on our Sun 3 under 4.0 this isn't what happens, so probably my recollection is faulty. So my question is: what is the standard (portable) way to do this? Am I doing it right? Thanks. -- -- Brian Glendenning - Radio astronomy, University of Toronto brian@radio.astro.utoronto.ca uunet!utai!radio!brian glendenn@utorphys.bitnet
maine@altair.dfrf.nasa.gov (Richard Maine) (05/31/89)
In article <BRIAN.89May31001207@radio.utoronto.ca> brian@radio.astro.utoronto.ca (Brian Glendenning) writes: > Now obviously I want to put NSIZE reals into LINE and write them out > later. My question is: what is the proper way to do this. On our Sun > 3 it looks like you fill up the last NSIZE elements of LINE and use a > write statement of the form: > WRITE( [...] REC=[...]) LINE(BIG-NSIZE+1) This would write only a single element, not NSIZE of them. Since the file was opened for direct access with a record length corresponding to NSIZE elements, this statement is illegal. I suppose it is possible that some implementation might fill up the record with succeeding elements, but it is certainly neither portable nor standard. > Is this the right thing to do in general? My recollection was that you > filled up the first NSIZE elements of LINE, and used a line like: > WRITE( [...] REC=[...]) LINE > and the fortran io would automatically take the appropriate number of > units of storage (RECL) from the beginning of line. This asks to write the whole line array. It is illegal and non-portable. I have seen implementations that would fill up the record with the first NSIZE elements (if you used err=... or iostat=... to get control back after the error), but you cannot count on it. The only portable way to do this is with an implied do loop as in WRITE( [...] REC=[...]) (LINE(I),I=1,NSIZE) or something equivalent. Hmm, forgot to mention one other approach, somewhat more roundabout, using adjustable array dimensions in subroutines. CALL SUB(LINE,NSIZE) ... SUBROUTINE SUB(LINE,NSIZE) REAL LINE(NSIZE) ... WRITE( [...] REC=[...]) LINE ... This is probably overly complicated unless it fits in naturally with other program structure. -- Richard Maine maine@elxsi.dfrf.nasa.gov [130.134.1.1]