Fl.pf.
Fl.pf.

Reputation: 345

Open file with part of name known

I have to

open(unit,file='x',status='old',action='read',iostat=io_error)

The problem is, i only know part of the name of the file since the last part is a number which changes every time the program is executed and I don't know the system in which the number is generated (extern library).

Is there a way to open the file with only a part of the name known?

Upvotes: 1

Views: 594

Answers (1)

casey
casey

Reputation: 6915

Unfortunately you'll need to know the filename before you can open it. One thing Fortran lacks in this regard is the ability to inspect the filesystem. Your options boil down to

  • EXECUTE_COMMAND_LINE or SYSTEM to call external programs, or
  • use iso_c_binding features to call C standard library functions.

I find the second option a bit cumbersome as the calls you'll need to make involve lots of typdef'd types, structures and C pointers. It is certainly doable but won't be the most straightforward if you aren't already familiar with Fortran/C interop.

Calling execute_command_line or system is 'easier' in the sense that if you can write a shell command to find your filename then you already have a solution.

As an example, I have a library that reads HDF5 data with N files, where N is based upon model timesteps and may be irregular. Rather than put the burden on the user to enumerate the files I was in a similar position as you. The way I'd solve your version of the problem would be something like this:

character(len=*), parameter :: temporary_file = '/tmp/something_unique'
character(len=*) :: filename_fragment, filename
integer :: u

call execute_command_line('find . -name '//trim(filename_fragment)// &
                          "* -printf '%f\n' > "//trim(temporary_file)
open(newunit=u, file=temporary_file, action="read")
read(u, '(A)') filename
close(u)

If filename_fragment is the part of the name you know, this is little more than a call to find with output redirected. E.g. if the filename_fragment is "datasetABC_" this would run

find . -name 'datasetABC_*' -printf '%f\n' > /tmp/something_unique

And the file /tmp/something_unique will contain one filename per line that matches your search. You may need to adjust the arguments to find to work for your specific case, but this is gives you the general idea of how to proceed. Once you have this working, you just open /tmp/something_unique and read your full filename(s) from the file and now you know the full name to open them with.

* Note: the solution above assumes your find will return only one filename. If it has multiple matches you'll need to either refine your search or handle that case within Fortran to get the correct file from the filenames in the temporary file.

Upvotes: 1

Related Questions