Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.
27794 Discussions

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

jimdempseyatthecove
Black Belt
431 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
Black Belt
417 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

 

jimdempseyatthecove
Black Belt
389 Views

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

 

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

 

Jim

IanH
Black Belt
382 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.

Ron_Green
Moderator
394 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.  

Ron_Green
Moderator
377 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

 

Steve_Lionel
Black Belt Retired Employee
374 Views

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

jimdempseyatthecove
Black Belt
366 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

Reply