Fortran non advancing reading of a text file

2019-03-05 07:11发布

问题:

I have a text file with a header of information followed by lines with just numbers, which are the data to be read.

I don't know how many lines are there in the header, and it is a variable number.

Here is an example:

filehandle:                65536
total # scientific data sets:        1
file description:
This file contains a Northern Hemisphere polar stereographic map of snow and ice coverage at 1024x1024 resolution.  The map was produced using the NOAA/NESDIS Interactive MultisensorSnow and Ice Mapping System (IMS) developed under the directionof the Interactive Processing Branch (IPB) of the Satellite Services Division (SSD).  For more information, contact:  Mr. Bruce Ramsay at bramsay@ssd.wwb.noaa.gov.

Data Set #       1
Data Label:                          
Northern Hemisphere 1024x1024 Snow & Ice Chart
Coordinate System:                   Polar Stereographic
Data Type:                           BYTE
Format:                              I3
Dimensions:                                  1024        1024
Min/Max Values:                         0 165
Units:                               8-bit Flag
Dimension #       0
  Dim Label:                         Longitude
  Dim Format:                        Device Coordinates
  Dim Units:                         Pixels
Dimension #       1
  Dim Label:                         Latitude
  Dim Format:                        Device Coordinates
  Dim Units:                         Pixels
1    0    0    0    0    0    0    0    0    0    0    0    0    0    0
 0
2    0    0    0    0    0    0    0    0    0    0    0    0    0    0
 0
3    0    0    0    0    0    0    0    0    0    0    0    0    0    0
 0
0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
 0
0    0    0    0    0    0    0    0    0    0    0    0    0    0    0
 0

..........................

I open the file using:

open(newunit=U, file = ValFile, STATUS = 'OLD', ACCESS = 'SEQUENTIAL', ACTION = 'READ')

Then, I read the file line by line and test for the type of line: header line or data line:

ios = 0
do while ( .NOT. is_iostat_end(ios)   )
    read(U, '(A)', iostat = ios, advance = 'NO') line ! Shouldn't advance to next line
    if (is_iostat_end(ios)) stop "End of file reached before data section."
    tol = getTypeOfLine(line, nValues) ! nValues = 1024, needed to test if line is data.
    if ( tol > 0 ) then   ! If the line holds data.
        exit    ! Exits the loop
    else
        read(U, '(A)', iostat = ios, advance = 'YES') line ! We advance to the next line
    end if
end do

But the first read in the loop, always advances to the next line, and this is a problem.

After exiting the above loop, enter a new loop to read the data:

read(U, '(1024I1)', iostat = ios) Values(c,:)

The 1024 set of data can span some lines, but each set is a row in the matrix "Values".

The problem is that this second loop doesn't read the last line read in the testing loop (which is the first line of data).

A possible solution is to read the lines in the testing loop, without advancing to the next line. I used for this, advance='no', but it still advances to the next line, Why?.

回答1:

A non-advancing read will still set the file position to before start of the next record if the end of the current record is encountered while reading from the file to satisfy the items in the output item list of the read statement - non-advancing doesn't mean "never-advancing". You can use the value assigned to the variable nominated in an iostat specifier for the read statement to see if the end of the current record was reached - use the IS_IOSTAT_EOR intrinsic or test against the equivalent value from ISO_FORTRAN_ENV.

(Implicit in the above is the fact that a non-advancing read still advances over the file positions that correspond to items actually read... hence once that getTypeOfLine procedure decides that it has a line of data at least part of that line has already been read. Unless you reposition the file subsequent "data" read statements will miss that part.)