- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is ACCESS='STREAM' compatible with FORM='BINARY'?
I do not want EOL (NEW_LINE) interfering with reads.
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
$ 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FORM='BINARY' is an old MS extension. ACCESS='STREAM', FORM='UNFORMATTED' is what you want.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page