Silverfrost Forums

Welcome to our forums

Unformatted files and BACKSPACE

12 Jan 2011 1:19 #7470

Hi

I am writing complex nos. to a file using unformatted sequential WRITE. I am writing these in batches of 310 complex nos. in a loop and then 93 complex nos. in the end.

After all of them have been written, I now need to read them back in reverse order, and I was trying to use BACKSPACE. However, on using BACKSPACE and reading the nos. back in, I get the following error: 110: Unformatted record is corrupt

I understand the complex no. storage is 8 bytes. When 310 complex nos. are written in a single record, 5 bytes are added to the start and end (i dont know exactly why 5 bytes are needed), making the record length to 310x8+10=2490. The end record is 93x8+10=754 long.

These nos. are as per the length of the file created. I am using the following to open the file: OPEN(3,FILE='FOO.FIL',FORM='UNFORMATTED',STATUS='REPLACE')

I have tried to do this operation without the end record and adding RECL=2490 to the OPEN Statement. Result is the same error.

Can somebody please throw some light ?

Thanks Abhishek

12 Jan 2011 1:54 #7471

These are only guesses:

If you closed the file after writing, and then re-opened it, the pointer is at the beginning, and you can't BACKSPACE.

If you kept the file open, you can BACKSPACE once, then read the last record. However, you will need to BACKSPACE twice to get at the record before that, and (assuming that you want to read the records in reverse order) you will need to BACKSPACE twice before reading each record. The reason is that each time you READ a record, the pointer to where you are in the file moves to the next record, so you have to move it back two records to get at the start of the record before the one you just read.

Was this of any use?

Eddie

12 Jan 2011 2:26 #7473

I am not closing the file.

I am using this in following fashion. For each ith read,

BACKSPACE(3) READ(3) BACKSPACE(3)

This way pointer should keep on getting backward.

12 Jan 2011 2:56 #7474

My second comment applies. It has to be

BACKSPACE READ ! for the last record BACKSPACE ! points you at the beginning of the last record BACKSPACE ! points you at the beginning of the previous record READ !reads the correct record BACKSPACE BACKSPACE

etc.

With only one BACKSPACE after the first time, you try to read a long record when your last record is short.

To check this, write the last record long as well (310 not 93 items). Put some data in that you will recognise. You will see that you keep reading the last record.

Eddie

12 Jan 2011 3:34 #7475

These lines are in a subroutine that gets called every time a READ has to be made.

Therefore, for every read, effectively the BACKSPACE statement is being called two times.

the error is thrown even for the first READ.

12 Jan 2011 11:42 #7479

I can't duplicate the error:

      PROGRAM COMP
      COMPLEX A(310), B(93), C(310), D(93)
      OPEN(3,FILE='FOO.FIL',FORM='UNFORMATTED',STATUS='REPLACE')
      A = 1.0
      B = 2.0
      C = 3.0
      D = 4.0
      WRITE(3) A
      WRITE(3) B
      BACKSPACE(3)
      READ(3) D
      BACKSPACE(3) 
      BACKSPACE(3)
      READ(3) C
      WRITE(*,*) C(1)
      WRITE(*,*) D(1)
      STOP
      END

This works, giving (1.000,0.000) and (2.000,0.000) whereas if D and C hadn't read the numbers printed would have been different! What does your code look like?

E

13 Jan 2011 2:40 #7480

I'd suggest you consider a fixed length record, direct access file. Open the file, with RECL= the maximum expected length (in bytes) = 2480 from what you have indicated.

OPEN(UNIT=13,FILE='FOO.FIL',FORM='UNFORMATTED',ACCESS='DIRECT',RECL=2480,STATUS='REPLACE',IOSTAT=iostat) If (iostat /= 0) then ... UNIT=3 is a risky number to use, I always use a number > 10

Then write the records with a REC= for the record number, starting from 1. The last record can be written (give the REC= as the next record number) As the I/O list is smaller, it will be padded out.

Then to read in reverse order, simply use the appropriate record number in REC=

END= is not a valid error test in a direct access file, so change to ERR=

John

14 Jan 2011 9:38 #7487

Actually I was using arrays to read and write in batches, something like

WRITE(3) ((BUF(N8,N9),N8=1,31),N9=1,10) and reading similarly

I found DIRECT access file to be much more reliable. Only thing is that RECL is variable in my case and can theoretically go upto 100x10x8=8000.

14 Jan 2011 4:18 #7498

Try this

      PROGRAM COMP 
      COMPLEX A(310), B(93), C(310), D(93) 
      OPEN(3,FILE='FOO.FIL',FORM='UNFORMATTED',STATUS='REPLACE') 
      A = 1.0 
      B = 2.0 
      C = 3.0 
      D = 4.0 
      WRITE(3) A 
      WRITE(3) B 
      REWIND(3) 
      READ(3) D 
      READ(3) C 
      WRITE(*,*) C(1) 
      WRITE(*,*) D(1) 
      STOP 
      END
15 Jan 2011 1:33 #7502

Yes REWIND is working. But REWIND positions the file at record 1, whereas I need to do backward reading.

Please login to reply.