Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Read and write direct access

Deleted_U_Intel
Employee
888 Views
I want to write in a file only one line (with text before and after this line) and replace this line for another one.
I have read that this is a "direct access" but I dont know how to use.
Can you help me?
0 Kudos
3 Replies
Jugoslav_Dujic
Valued Contributor II
888 Views
You need to open the file like:
OPEN(11, file="filename", ACCESS=DIRECT, RECL=irecl)
Now, the value ofirecl is troublesome.
First, indirect-access files, all records must be of the same length. If you're dealing with a file which is written as formatted sequential, with various length of records, you have a trouble. In the extreme case, you can use irecl of 1 byte -- in this case, you basically treat the file as an array of bytes.
Second, in CVF by default, however, irecl is expressed in longwords (4 bytes). So, you need to build with /assume:byterecl switch to get it expressed in bytes.
Then, you write your record as:
WRITE(11, REC=position) "Your text"//char(13)//char(10)
where position is the offset, in bytes, from the beginning of the file. Again, if the file is formatted, you have to count 2-byte record terminators(char(13)//char(10))This leads us to the third problem -- if the number of bytes in the file before your write varies (i.e. position is not constant), you can't know in advance at which position to overwrite the file. To find out, you can open the file as "SEQUENTIAL" before, skip appropriate number of records using READ(11,*), then call FTELL when you find "your" record to find out its byte offset (position). Then, CLOSE the file and OPEN it again with direct-access.
Are you sure you want to go through that? :-).
An alternative method is to just make the copy -- open the file as sequential, READ it record by record and WRITE the record into another sequential file (replacing "your" record when you find it). At the end, close both files, delete the old one and rename the new one.
Jugoslav
0 Kudos
Jugoslav_Dujic
Valued Contributor II
888 Views
If
1) your program spends so much time doing I/O as it sounds, and
2) the output is not meant to be human-readable,
I sincerely recommend switching to something other than FORMATTED files, i.e. UNFORMATTEDor BINARY (direct vs. sequential is your choice). These areMUCH faster to process (~10 times) and even simpler to program (once you get accustomed to) -- no messing with FORMAT statements/strings at all.
Jugoslav
0 Kudos
keefer
Beginner
888 Views
Hi,
Just a comment:
INQUIRE(IOLENGTH=direct_access_record_length) a,b,c
Will return the length in compiler default units (bytes, longwords) of *one* record comprised of a, b and c, whatever a,b, and c are (e.g. if c is a derived type or b is an array), you can change the definition of any of them and the compiler will keep track of things. (But remember if you write a file with a certain declaration of a, b and c, you can't read it again with code having different declarations of the variables)
Regards,
Keith
0 Kudos
Reply