# Use of Inquire to find Next record

**URL:** <https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292>\
**Category:** Help\
**Created:** [November 17, 2021, 10:39am UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292 "2021-11-17T10:39:14Z")\
**Posts on this page:** 10\
**Page:** 2

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [November 18, 2021, 4:46pm UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/21 "2021-11-18T16:46:07Z")

</div>

Partly due to just how many kinds of architectures Fortran has been around figuring out the number of records in a direct access file can be platform-specific. It can depend on which compiler and compiler options you choose and what hardware you are operating on. But usually now-adays query the size of the file and divide by the record length in bytes and you probably have the number of records.

Just be aware that not all OPEN statements are using bytes as the unit for the RECL option and that some rare environments that store files in interesting ways, usually for optimization purposes can cause other problems.

So if you are using one compiler with compiler options you are specifying this is easy; else it gets into a much longer discussion. I put a few hints on what else to look up if you do not have the simple case:

```fortran
program show
use ISO_FORTRAN_ENV, only : FILE_STORAGE_SIZE
implicit none
integer :: nexrec, ios, lun, i, sz, likely
character(len=256) :: message
integer,parameter :: ll=160
character(len=ll) :: line
   ! first program makes a file
   open(newunit=lun, file='DBPP', access='direct', &
   & status= 'replace', recl=ll,form='unformatted', &
   & iostat=ios, iomsg=message)
   do i=26,1,-1
      line=repeat(char(ichar('a')+i-1),ll)
      write(lun,rec=i)line
   enddo
   close(lun)
   write(*,*)'made and closed sample file'
   INQUIRE(IOLENGTH=likely) line
   ! second program reads a file
   open(newunit=lun, file='DBPP', access='direct', &
   & status= 'old', recl=ll,form='unformatted', &
   & iostat=ios, iomsg=message)
   if(ios.eq.0)then
      inquire(unit=lun, nextrec=nexrec,size=sz)
      print *,'the next record is ', nexrec
      print *,'the size is ', sz
      print *,'the file storage unit size is ', file_storage_size
      print *,'the iolength of a line is', likely
      if(likely.ne.ll)then ! not in bytes
      print *,'and your file is probably bigger than you need'
      print *,'because your RECL units are not bytes'
      print *,'the number of lines is probably ',sz/ll/(ll/likely)
      else
         print *,'your file probably has', sz/ll, 'records'
      endif
   else
      print *, '<ERROR>'//trim(message)
      stop 1
   endif
   print *, 'ready'
end program show

```

One common case is when using ifort(1) it depends on whether you compile with -assume byterecl or not, and so on, but probably all you need is:

```fortran
program show
implicit none
integer :: ios, lun, sz
character(len=256) :: message
integer,parameter :: ll=160
   open(newunit=lun, file='DBPP', access='direct', &
   & status= 'old', recl=ll,form='unformatted', &
   & iostat=ios, iomsg=message)
   if(ios.eq.0)then
      inquire(unit=lun, size=sz)
      print *,'the size is ', sz
      print *,'your file probably has', sz/ll, 'records'
   else
      print *, '<ERROR>'//trim(message)
      stop 1
   endif
   print *, 'ready'
end program show

```

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [November 18, 2021, 5:43pm UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/22 "2021-11-18T17:43:01Z")

</div>

PS: works with three compilers with switches as shown

```nohighlight
 ifort exa2.f90 -assume byterecl
urbanjs@venus:~$ ./a.out
 the size is 4160
 your file probably has 26 records
 ready
urbanjs@venus:~$ gfortran exa2.f90
urbanjs@venus:~$ ./a.out
 the size is 4160
 your file probably has 26 records
 ready
urbanjs@venus:~$ nvfortran exa2.f90
urbanjs@venus:~$ ./a.out
 the size is 4160
 your file probably has 26 records
 ready

```

how many bytes does your file have, and what compiler command(s) are you using?

Here is an example of a compile where the RECL length is not bytes, that shows an error I find a lot where the code will run just find but often 3/4 of the file is unused data, just to show an example where it is not that simple:

```nohighlight
ifort exa.f90 -assume nobyterecl
urbanjs@venus:~$ ./a.out
 made and closed sample file
 the next record is 1
 the size is 16640
 the file storage unit size is 8
 the iolength of a line is 40
 and your file is probably bigger than you need
 because your RECL units are not bytes
 the number of lines is probably 26
 ready

```

That is a simple mistake and a bigger deal when the files are a Terabyte in size! The file only needs to be 4096 bytes but in this case is four times larger; but the code will run just fine.

One of my favorites with direct access files is where people do something like ENTRY=ENTRY+1 and write to REC=ENTRY but ENTRY was never initialized, often because someone assumed it would always be initialized to zero. Programs crash, get wrong answers, create bad output files, fill file systems, exceed file size limits or even crash machines when ENTRY is not initially zero; from just one uninitialized value.

---

<div class="post-metadata">

**Author:** ![miramar46](https://avatars.discourse-cdn.com/v4/letter/m/e79b87/32.png) [@miramar46](https://fortran-lang.discourse.group/u/miramar46)\
**Post date:** [November 18, 2021, 8:22pm UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/23 "2021-11-18T20:22:40Z")

</div>

I am using Lahey-Fujitsu v7.3 for 32 bit windows. I don’t have any special compiler options but I did find in the Users Guide the following that I think are applicable to my situation:  
d[num] 1  
The d option determines the size of the input/output work area used by a direct access input/  
output statement. The d option improves input/output performance when data is read from or  
written to files a record at a time in sequential record-number order. If the d option is specified,  
the input/output work area size is used for all units used during execution.  
To specify the size of the input/output work area for individual units, specify the number of  
Fortran records in the environment variable FUnnBF where nn is the unit number (see“Environment  
Variables for Input/Output” on page 136 for details). When the d option and  
environment variable are specified at the same time, the d option takes precedence. The  
optional argument num specifies the number of Fortran records, in fixed-block format,  
included in one block. The optional argument num must be an integer from 1 to 32767. To  
obtain the input/output work area size, multiply num by the value specified in the RECL=  
specifier of the OPEN statement. If the files are shared by several processes, the number of  
Fortran records per block must be 1. If the d option is omitted, the size of the input/output  
work area isFUnnBF = size  
The FUnnBF environment variable specifies the size of the input/output work area used by a  
sequential or direct access input/output statement. The value nn in the FUnnBF environment  
variable specifies the unit number. The size argument used for sequential access input/output  
statements is in kilobytes; the size argument used for direct access input/output statements is  
in records. The size argument must be an integer with a value of 1 or more. A size argument  
must be specified for every unit number.  
If this environment variable and the g option are omitted, the input/output work area size used  
by sequential access input/output statements defaults to 1 kilobytes. The size argument for  
direct access input/output statements is the number of Fortran records per block in fixedblock  
format. The size argument must be an integer from 1 to 32767 that indicates the number  
of Fortran records per block. If this environment variable and the d option are omitted, the  
area size is 1K bytes.  
According to the operating system this file DBPP is 3840 bytes with only the 25 records it has now.  
When I first created the file DBPP, Inquire said the RECL=160 ; so for 25 records that would be 4000 bytes. Which agrees with 4160 you got for 26 records. Do you think I should try these compiler switches d[num]1 and FUnnBF? Thanks for your help. Floyd

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [November 19, 2021, 12:51am UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/24 "2021-11-19T00:51:54Z")

</div>

Those parameters are useful for optimizing I/O by changing the cache area size used for I/O buffering. The online manual indicates specifically that RECL= is in bytes for both OPEN and INQUIRE so the last example should work as-is for your file. It is not guaranteed by the Fortran standard but the file is very likely a stream of bytesn on your local file system and will be of the size 160\*number of lines and since all direct access records are by definition the same size, and particularly because your record length is a multiple of four and you are on a standard platform type it is extremely likely the last sample program will work. It is highly likely that the file only contains 24 lines, and that if you except 25 that is probably an issue with the program that wrote the file, not the above technique. So with the caveat that it is not portable to all platforms just query the size with INQUIRE() and divide by the length of your records (160) and you should get the number of records. Does the last sample program work and show the size as 3840 and the number of lines as 24?

---

<div class="post-metadata">

**Author:** ![miramar46](https://avatars.discourse-cdn.com/v4/letter/m/e79b87/32.png) [@miramar46](https://fortran-lang.discourse.group/u/miramar46)\
**Post date:** [November 19, 2021, 11:37am UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/25 "2021-11-19T11:37:06Z")

</div>

Some of the specifiers in your code don’t work on my compiler. I looked in the Language Reference and both iomsg and size are not allowed in the open statement. I did add the INQUIRE for iolength but I still get nexrec=1 and iolength=0  
I did not add the code where you make the sample file writing from 26 to 1 in minus one step??  
What is the purpose of that? I already have the file written and I know it contains 25 records that are good. I have another program that gets the data from ‘DBPP’ and writes it to an output file. The results are all correct. I don’t understand the reason why your program works and mine doesn’t  
Floyd

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [November 19, 2021, 1:08pm UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/26 "2021-11-19T13:08:35Z")

</div>

Miramar46,

A nice [discussion](https://comp.lang.fortran.narkive.com/7nsr4Hmz/detect-eof-for-direct-access-unformatted-files) of the properties of direct access files, dating back 17 years, may be useful to you.

My view is that the entire task is easily accomplished with a text editor or a spreadsheet program, given that the whole “database” is less than 100 records of 160 characters each. If you insist on writing a Fortran program for maintaining such short files, note that direct access gives you insignificant benefits over sequential access, and the limitations of direct access files make them unsuited for the intended application.

Consider, as well, that a commodity computer today has about 8 GB or RAM, of which at least 1 or 2 GB can be used to hold _millions_ of 160-byte records. It is, therefore, convenient and less error-prone to read the entire data into memory, do all the addition-deletion-modification operations in memory, and write the revised data back to a new version of the data file. We do not have to perform record-oriented I/O as if we were using a 1960-s business oriented computer.

---

<div class="post-metadata">

**Author:** ![miramar46](https://avatars.discourse-cdn.com/v4/letter/m/e79b87/32.png) [@miramar46](https://fortran-lang.discourse.group/u/miramar46)\
**Post date:** [November 19, 2021, 1:19pm UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/27 "2021-11-19T13:19:15Z")

</div>

I am beginning to think of switching to sequential since direct access has been so difficult.  
However, I don’t think I can access data from a spreadsheet into a fortran program. Am I wrong?  
I want to write some programs which need some not all of these physical properties in the file ‘DBPP’. The choice of which compounds to be read into the program depends on the user.

Thank you for your help,  
Floyd Pfeffer

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [November 19, 2021, 1:26pm UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/28 "2021-11-19T13:26:42Z")

</div>

> [@miramar46](#):
>
> I am beginning to think of switching to sequential since direct access has been so difficult.  
> However, I don’t think I can access data from a spreadsheet into a fortran program. Am I wrong?

I save Excel files as csv files and read those from Fortran. Discussion of reading .xls files directly using Intel Fortran is [here](https://community.intel.com/t5/Intel-Fortran-Compiler/Reading-and-Writing-of-Excel/td-p/1151744). Excel can export files to XML, which there are Fortran libraries to read.

---

<div class="post-metadata">

**Author:** ![mecej4](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mecej4/32/855_2.png) [@mecej4](https://fortran-lang.discourse.group/u/mecej4)\
**Post date:** [November 19, 2021, 1:28pm UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/29 "2021-11-19T13:28:10Z")

</div>

I don’t use spreadsheets, but I believe that any spreadsheet program in use today will have the capability of writing (“exporting”) data of the kind that you have into a CSV (comma-separated-values) file, which can be read as a formatted sequential file by a Fortran program.

---

<div class="post-metadata">

**Author:** ![JohnCampbell](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@JohnCampbell](https://fortran-lang.discourse.group/u/JohnCampbell)\
**Post date:** [November 26, 2021, 2:19am UTC](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292/30 "2021-11-26T02:19:00Z")

</div>

Another complexity, it is **my understanding** is that direct access files do not have to be written sequentially. (Happy to be corrected if I am wrong about this)  
This means that Nextrec is not essential for extending a direct access file.  
What is important for you to know is which records have been written and are still valid.  
Records can be written, read or updated in any order.

One of the key limitations of direct access files is that record lengths are fixed as all being the same.

I am at present experimenting with stream I/O, which also has a direct addressing capability for random I/O but also supports variable length records. You must manage the individual record addresses and properties. So, providing you keep a table of records, their size and location, this can be a much more flexible record structure format. I expect there is a limitation that stream I/O files must be written sequentially, so Last\_Rec (or Last\_Pos) is an important property.  
You can also construct records with a header:data:trailer structure to enable sequential access or reconstructing the record table. The header and trailer can be an 8-byte integer to remove any 2-gbyte size limits as can occur with some 32-bit (derived) Fortran compilers.  
This record structure can be managed via library routines, while retaining Fortran read/write I/O list flexibility for the data component.  
Lots of potential for full 64-bit support.

[Previous page](https://fortran-lang.discourse.group/t/use-of-inquire-to-find-next-record/2292.md?page=1)
