Accessing inputs and outputs folders in any directory

Hi Everyone,

Before stating my question i’ll give some backround information. I am using Fortran 77 with the gfortran compiler (version 3.6.0). I am working on some routines not written by me which are then called in a matlab main code.

So, i have a question on how Fortran handles files and directories. Right now i know that by using the OPEN statement i need to specify the exact directory of the files i wish to read or to write on. Now, my intent is to be able to create an executable that can access files in any directory in which is called by the matlab main code.

As an example, lets say that the executable is kept in a folder called Executable, while the matlab main is kept inside the folder MAIN CODE together with the two files named Inputs and Outputs. What i want to be able to do is for the executable to be able to find and read the Inputs file without specifying inside the OPEN statement the full directory (similarly with the Outputs file); as if i did so, then the executable will only be working if the matlab main code were to reside inside the MAIN CODE folder.

Now, i know for a fact that this is in theory possible. The executables that were passed to me work this way. However, when i compile it myself with some corrections this functionality is lost and i have no idea on why since my corrections are absolutely minor (one line) and does not at all regard the opening, reading and writing of the files.

I hope i’ve been clear in stating my problem. In any case, let me know if i was not, i’ll try to make myself clearer. Thanks for the attention!

Best regards,
Giulio

Possibly I don’t understand the question (I know little about Matlab) but have you tried specifying the filename without any path? That should look for the file in the current directory. e.g.:

open(unit=10,file="foo.dat")`

I think that executed inside Matlab:

pwd

will probably tell you what the current directory is.

Thank you for taking the time to answer me. The problem is basically that. I don’t want for the executable to search in its current directory (in my example inside the Executable folder). I want for it to search the inputs and outputs inside whichever folder name the Matlab main is residing (in my example MAIN CODE, but i could be any other name).

You should do it from Matlab as only Matlab may know where its files are.

You can use mfilename to get the filename and the path of your Matlab main function, then you can pass it to your Fortran executable (if you can pass parameter to it) or you can change the current directory for example with oldfolder = cd(newfolder), run you Fortran executable and change the folder back to the previous one.

If you run the fortran code from the MAIN CODE directory (where are the Inputs/Outputs files).
Then, in your fortran code, you just need:

open(unit=10,file=“Inputs”)

As suggested by @feenberg.

I’m not sure how Matlab works, but in general, that is not the way you run programs on a computer. One usually has a directory (i.e. folder) that has the input and output files for a job. One then makes that directory the working directory (e.g. with a cd command). The directory that has the executable program is somewhere else, not the default. You seem to be trying to do it the other way around.

The fortran program then first looks in the default directory for any filename references. If it finds them there it uses them, otherwise it creates them there in that default directory.

If you want to look for files elsewhere, then you must specify where somehow. There are several ways. One way is to just read in the full file name as part of the input data. You then use those file names in the open statements for the files. Instead of the full file name, you can use relative addressing, such as “../sub/filename” in the open statement, which would look up one level, then look for a directory named “sub” in that parent directory, and then within that directory it would look for a file named “filename”. Note that you do not need to know the name of the parent directory, the ../ is a file alias that always points to the parent.

Another way is to get the file and directory name from an environment variable. You translate the environment variable, with GET_ENVIRONMENT_VARIABLE(), and the use the result of that translation in the open statement. Sometimes you get just the directory name from the environment and append the desired file names manually.

Another way is to use redirection on the command line, e.g. command < dirname/filename. Your fortran program reads from standard input, which is connected to that file name by the operating system and shell. You can redirect standard output and standard error this way too.

Another way is to specify the list of files on the command line, e.g. “command dir1/file1 dir2/file2 dir3/file3”. You then read those arguments with GET_COMMAND_ARGUMENT() and use them in the open statements.

All of that can now be done entirely with standard fortran routines, there is no longer any need to use compiler-specific extensions for these operations. However, you can still use compiler-specific functions for this too. On MacOS for example, many compilers provide an interface routine to the standard MacOS file dialogue popup window. The method you choose depends on which approach fits best with your needs.

I’m just curious, what is the constraint holding you back to a compiler release from ~ 2005? Is it the Fortran compiler shipped with a particular (old) version of MATLAB?


The suggestion of Ron to use environment variables could look something like this:

% --- MATLAB code ---

% Get current work directory 
% (https://www.mathworks.com/help/matlab/ref/pwd.html)
currentFolder = pwd

% Set an environment variable 
% (https://www.mathworks.com/help/matlab/ref/setenv.html)
setenv("MATLAB_WORK_FOLDER",currentFolder)

% Call Fortran/MEX routine
do_calculation( ... )
C  called from within do_calculation, or
C  linked into an independent executable
C
      subroutine fortran_calculation( ... )
      implicit none
C ... input declarations
      character(len=256) folder
      integer io
      parameter(io=42)
C NB: getenv is a GNU Fortran 77 extension, 
C     use get_environment_variable if possible
      call getenv("MATLAB_WORK_FOLDER",folder) 
C ... statements
      if (trim(folder) /= '') then
         open(io,file=trim(folder)//"file.txt",status="old")
C ...
         close(io)
      end if
      end

Thank you all for your suggestions. I will try them in the next days and will post updates! Thank you again!!

Hello everyone,

I ended figuring out what the problem was. Apparently some versions of Matlab have a problem when a fortran source code is compiled in 32 bit and not 64. So, it searches for the wrong libraries. What ones needs to add to its matlab code as the following example:

system('set path=%PATH:C:\Software\MATLAB\R2021a\bin\win64;=% & .\integrale.exe')

So you need to specify the directory for Matlabs win64 together with the directory of the executable.

Thanks again to everyone.