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

INQUIRE(unit, POS=pos) returns 0 regardless of position

jimdempseyatthecove
Honored Contributor III
1,333 Views

I wish to add some defensive code to protect against reading beyond end of file of a binary file. I know the size of the file and I need to determine the size of the remainder of the file from the current position.

!$omp critical(zzz)
inquire(unit, POS=pos)! returns 0 regardless of position
remainder = (fileSize - pos)/sizeof(array(1)) ! number of array elements remaining
ub = min(remaining,size(array))
read(unit) array(1:ub)  ! may read short (without eof error)
!$omm end critical(zzz)

oneAPI 2022.0.0.161

 

Jim Dempsey

0 Kudos
7 Replies
IanH
Honored Contributor III
1,319 Views

Simple example works for me.  Confirm you are using stream access.

PROGRAM TestInquire
  IMPLICIT NONE
  
  INTEGER :: unit             ! Unit for I/O
  INTEGER :: i                ! Counter
  INTEGER :: pos              ! File position
  REAL :: r                   ! Value read from file.
  
  OPEN( NEWUNIT=unit,  &
      FILE='TestInquire.dat',  &
      ACCESS='STREAM',  &
      FORM='UNFORMATTED',  &
      ACTION='WRITE',  &
      STATUS='REPLACE' )
  DO i = 1, 10
    IF (i == 5) INQUIRE (unit, POS=pos)
    WRITE (unit) REAL(i, KIND=KIND(r))
  END DO
  CLOSE(unit)
  
  r = 0.0
  OPEN( NEWUNIT=unit,  &
      FILE='TestInquire.dat',  &
      ACCESS='STREAM',  &
      FORM='UNFORMATTED',  &
      ACTION='READ',  &
      STATUS='OLD' )
  READ (unit, POS=pos) r
  CLOSE(unit)
  
  PRINT *, r
END PROGRAM TestInquire

 

>ifort /check:all /warn:all /standard-semantics test-inquire.f90 && test-inquire.exe
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.5.0 Build 20211109_000000
Copyright (C) 1985-2021 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.29.30140.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:test-inquire.exe
-subsystem:console
test-inquire.obj
 5.000000

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,291 Views

Is ACCESS='STREAM' compatible with FORM='BINARY'?

 

I do not want EOL (NEW_LINE) interfering with reads.

 

Jim

0 Kudos
IanH
Honored Contributor III
1,284 Views

Under the Fortran standard (i.e. vendor extensions aside), ACCESS='STREAM' is required for INQUIRE(... POS=xxx) to be meaningful.  See last sentence of 12.10.2.22p1 in F2018.

If there is no connection, the file is not connected for stream access, or if the position of the file is indeterminate because of previous error conditions, the variable (the thing nominated by the POS= specifier) becomes undefined.

I'd expect ACCESS='STREAM', FORM='UNFORMATTED' (~ connect the file as a stream of bytes, no concept of lines or records) to be the standard conforming equivalent of the FORM='BINARY' vendor language extension, but there might be devil in the details.

0 Kudos
Ron_Green
Moderator
1,296 Views

this is a read-only file?  Or if you're writing also, it's also ONLY in an OMP critical section 'zzz'.  

And you have turned off file buffering?

And the file system is local disk, or NFS (or Windows equivalent) with caching disabled? 

And you're not using MPI across multiple nodes, where each rank may be accessing this file remotely?

So many complications with file systems and parallelism.  

0 Kudos
Ron_Green
Moderator
1,279 Views
$ more bin.f90
program bin
implicit none
real :: deadbf = X'deadbeef'

open( 42,file='stream', access='stream', form='unformatted')
open( 43,file='binary', form='binary')

write(42) deadbf
write(43) deadbf

close(42)
close(43)
end program bin
$ 
$ !ifort
ifort bin.f90
$ ./a.out
$ 
$ od -ax stream
0000000   o   >   -   ^
           beef    dead
0000004

$ od -ax binary
0000000   o   >   -   ^
           beef    dead
0000004
[rwgreen@orcsle162 tmp]$ 

linux result, both files are what you expect

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,276 Views

FORM='BINARY' is an old MS extension. ACCESS='STREAM', FORM='UNFORMATTED' is what you want.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,268 Views

>>FORM='BINARY' is an old MS extension. ACCESS='STREAM', FORM='UNFORMATTED' is what you want.

Ok thanks. Will change that

fwiw

FORM='BINARY', ACCESS='STREAM' works

 

The above solves my initial issue. I had resolved this by keeping track of the number of bytes read against the original file size. This works when reading a binary/unformatted file that is not extended while open.

The is (will be) an issue when writing the file, the above fix will be suitable for use there (unformatted files)

 

Jim

0 Kudos
Reply