Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
1 View

Sequential WRITE with variable record length

Jump to solution

I have been trying to read and write some files in Fortran, but my knwoledge on IO is pretty limited. I have been opening the file with

OPEN(NEWUNIT=file_unit, FILE=filename, STATUS='replace', IOSTAT=file_status, &
                         ACTION='write', ACCESS='sequential', FORM="unformatted")

and writes are in a loop with

WRITE(file_unit, IOSTAT=file_status) var1,var2,var3...

That's all fine for writing and I get no errors. The problem is that I don't know the size of the records; the type of the variables var1 var2 and var3 MAY change between writes. When trying to read, I open the file in exactly the same way, but when I try to read

CHARACTER(LEN=1024) :: longbuf

(...)

READ(file_unit, IOSTAT=file_status) longbuf

I get IOSTAT=67 although it does read the file properly: It reads only "one record" and stores it in the longbuf variable. After going through all the records in the file it gives me the proper EOF IOSTAT which is -1.

My question is, am I doing this in the best way? What does the IOSTAT 67 stand for? I've seen that there is a IS_IOSTAT_EOF function in F2003, are there other similar intrinsic?

Thanks in advance!

0 Kudos

Accepted Solutions
Highlighted
1 View

All of the IOSTAT values are

Jump to solution

All of the IOSTAT values are documented - there's also IOMSG which will give you a text version. 67 is "Input statement requires too much data", which is what you get when you try to read a 1024 byte variable from a record that's shorter.

A basic problem you have is that unformatted I/O assumes that you know exactly what you're reading, since it's a straight transfer of bits. How were you planning to separate out the values if you read it into a string buffer?

Sequential unformatted I/O isn't really suitable to a program where the types and sizes of variables changes unpredictably with each WRITE. What you might be able to do is open the file ACCESS='STREAM' so that there is no record structure, and precede the variables with some sort of code that tells you what is to follow. When reading, read the code first, then choose an appropriate READ to get the values.

Retired 12/31/2016

View solution in original post

0 Kudos
3 Replies
Highlighted
2 Views

All of the IOSTAT values are

Jump to solution

All of the IOSTAT values are documented - there's also IOMSG which will give you a text version. 67 is "Input statement requires too much data", which is what you get when you try to read a 1024 byte variable from a record that's shorter.

A basic problem you have is that unformatted I/O assumes that you know exactly what you're reading, since it's a straight transfer of bits. How were you planning to separate out the values if you read it into a string buffer?

Sequential unformatted I/O isn't really suitable to a program where the types and sizes of variables changes unpredictably with each WRITE. What you might be able to do is open the file ACCESS='STREAM' so that there is no record structure, and precede the variables with some sort of code that tells you what is to follow. When reading, read the code first, then choose an appropriate READ to get the values.

Retired 12/31/2016

View solution in original post

0 Kudos
Highlighted
Beginner
1 View

Quote:Steve Lionel (Intel)

Jump to solution

Steve Lionel (Intel) wrote:

All of the IOSTAT values are documented - there's also IOMSG which will give you a text version. 67 is "Input statement requires too much data", which is what you get when you try to read a 1024 byte variable from a record that's shorter.

A basic problem you have is that unformatted I/O assumes that you know exactly what you're reading, since it's a straight transfer of bits. How were you planning to separate out the values if you read it into a string buffer?

Sequential unformatted I/O isn't really suitable to a program where the types and sizes of variables changes unpredictably with each WRITE. What you might be able to do is open the file ACCESS='STREAM' so that there is no record structure, and precede the variables with some sort of code that tells you what is to follow. When reading, read the code first, then choose an appropriate READ to get the values.

I didn't have a very clear idea on how to split the data from a string buffer. Can't Fortran re-interpret a sequence of bytes regardless of the type it was assigned? 

In any case, your suggestion is far better. I am writing now it as a stream, and registering the type and kind of the variable that will follow. Works flawlessly, thanks!

0 Kudos
Highlighted
1 View

There are ways to

Jump to solution

There are ways to "reinterpret" the type, but you have to know which type you want first. Furthermore, with sequential unformatted files you need to know in advance how many bytes you want to read from a record, which is why stream works better for your application.

Retired 12/31/2016
0 Kudos