# How to test if a directory exists?

**URL:** <https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731>\
**Category:** Uncategorized\
**Created:** [October 18, 2024, 8:06am UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731 "2024-10-18T08:06:16Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Arjan](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/arjan/32/4448_2.png) [@Arjan](https://fortran-lang.discourse.group/u/Arjan)\
**Post date:** [October 18, 2024, 8:06am UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/1 "2024-10-18T08:06:16Z")

</div>

Hi,  
With INQUIRE, I can check if a file exists. How do I do the same for a directory?  
Regards,

Arjan

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [October 18, 2024, 9:11am UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/2 "2024-10-18T09:11:04Z")

</div>

From a 2007 answer on the [Intel Fortran forum](http://community.intel.com/t5/Intel-Fortran-Compiler/Detecting-file-directory-existence/m-p/833585#M53694):

> So, there is no Fortran standard way to ask if a directory exists.(Ignoring for now that even the syntax for directories is non-portable.) The closest you can come is the POSIX routine PXFOPENDIR which opens a directory. For compilers that support the POSIX Fortran library, this should be reasonably portable.

I also found a couple suggestions on StackOverflow (but none are really definitive): [Test whether a directory exists or not](https://stackoverflow.com/questions/9522933/test-whether-a-directory-exists-or-not)

* * *

One option I’m aware of is the Fortran [filesystem](https://github.com/scivision/fortran-filesystem) library, which effectively wraps the [C++17 filesystem](https://en.cppreference.com/w/cpp/filesystem) library. An example would look like:

```fortran
use filesystem, only : path_t
type(path_t) :: p

p = path_t("my/path")

print *, p%exists() .and. p%is_dir()

```

Another option would be the [`is_dir`](https://github.com/fortran-lang/fpm/blob/448d47c483b331e7654a2a18dead70a2820cee49/src/fpm_filesystem.F90#L211) function from the `fpm_filesystem` module:

This should be as simple as,

```fortran
use fpm_filesystem, only: is_dir
print *, is_dir("my/path")

```

---

<div class="post-metadata">

**Author:** ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)\
**Post date:** [October 18, 2024, 9:25am UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/3 "2024-10-18T09:25:28Z")

</div>

In this Open PR for stdlib [Add filesystem interaction by minhqdao · Pull Request #874 · fortran-lang/stdlib · GitHub](https://github.com/fortran-lang/stdlib/pull/874) @minhdao is working on several functionalities for file system interaction among which a “exists” function for files and paths. From here I learned that Intel Fortran enables using `inquire` with a directory argument [https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2023-2/inquire.html](https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2023-2/inquire.html)

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [October 18, 2024, 10:09am UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/4 "2024-10-18T10:09:15Z")

</div>

A Fortran-only “solution” might be:

- First chose some arbitrary name, like “xx” and check if a file of that name exists in the directory you want check. If so, you are done.
- Otherwise, open the file in that directory and check that that is successful. Problem is, it might be that you have no access to the directory. Close it with the clause “status = ‘delete’” to leave as little garbage as possible,
- The drawback of this method: the timestamp for the directory will change.  
This is not foolproof and it leaves a stain, but it might be sufficient for your purpose.

---

<div class="post-metadata">

**Author:** ![andrew\_4619](https://avatars.discourse-cdn.com/v4/letter/a/e68b1a/32.png) [@andrew\_4619](https://fortran-lang.discourse.group/u/andrew_4619)\
**Post date:** [October 18, 2024, 12:28pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/5 "2024-10-18T12:28:13Z")

</div>

There is OS dependence in this. On windows I pass the file entity string to GetFileAttributes and the iand(attrib,FILE\_ATTRIBUTE\_DIRECTORY) \> 0 tells you it is a folder. I should add those are windows sdk things in say IFWIN on intel fortran.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [October 18, 2024, 12:41pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/6 "2024-10-18T12:41:43Z")

</div>

Not a pure Fortran solution but the following appears to work on my Linux systems. Not sure about Windows.

C code that uses opendir() to test for a directory. Taken from stackoverflow post.

```auto
/* dir_exists.c */

#include <dirent.h>
#include <errno.h>

extern int dir_exists(const char *dir_path)
{

/* code taken from stackoverflow post */

DIR* dir = opendir(dir_path);
if (dir) {
    /* Directory exists. */
    closedir(dir);
    return 0;
} else if (ENOENT == errno) {
    return 1;
    /* Directory does not exist. */
} else {
    return -1;
    /* opendir() failed for some other reason. */
}
}

```

check\_dir function that wraps dir\_exists and test program.

```auto
Program test_dir

  Implicit NONE

  Character(:), Allocatable :: lib_path
  Character(:), Allocatable :: nodir_path

! Check for non-existent dir

  lib_path = "/usr/lib64"
  nodir_path = "/usr/somedir"

  If (check_dir(lib_path)) Then
    Print *, TRIM(ADJUSTL(lib_path))//" exists"
  Else
    Print *, TRIM(ADJUSTL(lib_path))//" doesn't exist"
  End If

  If (check_dir(nodir_path)) Then
    Print *, TRIM(ADJUSTL(nodir_path))//" exists"
  Else
    Print *, TRIM(ADJUSTL(nodir_path))//" doesn't exist"
  End If

Contains

  Logical Function check_dir(dir_path)

    USE ISO_C_BINDING, ONLY: C_INT, C_CHAR, C_NULL_CHAR
    Implicit NONE

    Character(*), Intent(IN) :: dir_path

    Interface
      Function c_dir_exists(dir_path) BIND(C,NAME="dir_exists")

        IMPORT :: C_INT, C_CHAR

        Character(KIND=C_CHAR), Intent(IN) :: dir_path(*)
        Integer(C_INT) :: c_dir_exists

      End Function c_dir_exists
    End Interface

    Character(:), ALLOCATABLE :: c_path 

    c_path = TRIM(ADJUSTL(dir_path))//C_NULL_CHAR
    check_dir = (c_dir_exists(c_path) == 0_C_INT)

  End Function check_dir

End Program test_dir

```

---

<div class="post-metadata">

**Author:** ![davidpfister](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/davidpfister/32/3949_2.png) [@davidpfister](https://fortran-lang.discourse.group/u/davidpfister)\
**Post date:** [October 18, 2024, 1:14pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/7 "2024-10-18T13:14:16Z")

</div>

Windows does not have dirent but you can always add it through this project: [dirent](https://github.com/tronkko/dirent)

---

<div class="post-metadata">

**Author:** ![interkosmos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/interkosmos/32/296_2.png) [@interkosmos](https://fortran-lang.discourse.group/u/interkosmos)\
**Post date:** [October 18, 2024, 1:16pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/8 "2024-10-18T13:16:21Z")

</div>

Another solution for Linux/FreeBSD, using the [fortran-unix](https://github.com/interkosmos/fortran-unix) bindings:

```fortran
logical function is_dir(path)
    use :: unix
    character(len=*), intent(in) :: path

    integer :: file_type, stat
    integer(kind=c_int64_t) :: mode
    type(c_stat_type) :: fs

    is_dir = .false.

    stat = c_stat(trim(path) // c_null_char, fs)
    if (stat /= 0) return

    mode = c_uint32_to_int64(fs%st_mode)
    file_type = int(iand(mode, int(S_IFMT, kind=c_int64_t)))

    is_dir = (file_type == S_IFDIR)
end function is_dir

```

---

<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:** [October 18, 2024, 1:20pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/9 "2024-10-18T13:20:40Z")

</div>

When using Windows, I would try to create a file in the directory. If it works then ok, otherwise there is a problem; most likely the directory does not exist or is not available.  
I mainly use local windows drives, so this approach works for my experience.

---

<div class="post-metadata">

**Author:** ![davidpfister](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/davidpfister/32/3949_2.png) [@davidpfister](https://fortran-lang.discourse.group/u/davidpfister)\
**Post date:** [October 18, 2024, 1:33pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/10 "2024-10-18T13:33:15Z")

</div>

Alternatively, you can create a binding to [GetFileAttributes](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileattributesa?redirectedfrom=MSDN). You can then check if the return value equals **FILE\_ATTRIBUTE\_DIRECTORY** 16 (0x00000010)

---

<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:** [October 18, 2024, 2:00pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/11 "2024-10-18T14:00:26Z")

</div>

There is no standard intrinsic or statement to determine if a pathname is a directory.  
The answer varies depending on how portable the solution has to be.

o is it only needed in Microsoft environments?  
o is it only needed in POSIX environments?  
o is there always a shell of the same brand available, like POSIX shells (sh,bash,ksh,…)?  
o is it only needed for a particular compiler?

o some compilers have an extension intrinsic, typically called ISDIR().

o in a POSIX environment it is easy to use a little C wrapper to isolate you from  
whether C is implementing some functionality as a macro or not that you can then  
call.

o there are often commands you can call with EXECUTE\_COMMAND\_LINE like  
the Bourne shell “test” command, where the exit status of the command  
can be used to determine many properties.

In addition to what has been mentioned, note

In a POSIX environment the github repositories (available via fpm(1)) have  
several alternatives, such as system\_isdir() and is\_dir(). Both repositories  
and code have extensive help text.

```toml
[dependencies]
M_path = { git = "https://github.com/urbanjost/M_path.git" }
M_system = { git = "https://github.com/urbanjost/M_system.git" }

```

The fpm command has both an example of using system commands (is\_dir) and using a C interface  
(c\_is\_dir).

Depending on the compiler(s) you are using, see if the ISDIR() extension is present.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [October 18, 2024, 2:43pm UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/12 "2024-10-18T14:43:16Z")

</div>

With unix/posix type file systems, a directory is just a special kind of file, so you can test for the existence of a directory the same way you test a file. Here is a toy program that demonstrates this:

```auto
program dir
   character(255) :: dname = '/'
   logical :: dexist = .false.
   character(*), parameter :: cfmt='(*(g0))'
   write(*,cfmt) 'input the directory name:'
   read(*,'(a)') dname
   write(*,cfmt) 'testing for existence of ', trim(dname)
   inquire( file=dname, exist=dexist )
   write(*,cfmt) 'exist=', dexist
end program dir

$ gfortran dir.f90 && a.out
input the directory name:
./none
testing for existence of ./none
exist=F
$ a.out
input the directory name:
../work
testing for existence of ../work
exist=T

```

There is no file or directory in my cwd called `./none`, so the above is correct. My cwd is `../work`, so that directory does exist. Notice that `./` and `../` work for relative file names as expected because those are file system entries, not shell variables. If you do want to use a shell variable, then it must be translated first with the `GET_ENVIRONMENT_VARIABLE()` intrinsic.

If you want to distinguish between a file and a directory, then the other posts in this thread show how to do that. That is operating system specific and goes beyond standard fortran. But if you know already the name of the directory, and that it is indeed a directory and not a regular file, then you can test for it with just standard fortran as above.

---

<div class="post-metadata">

**Author:** ![eugene\_epshteyn](https://avatars.discourse-cdn.com/v4/letter/e/8797f3/32.png) [@eugene\_epshteyn](https://fortran-lang.discourse.group/u/eugene_epshteyn)\
**Post date:** [October 20, 2024, 5:44am UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/13 "2024-10-20T05:44:59Z")

</div>

INQUIRE() should also work for directories with ifx: [https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2024-2/obtain-file-information-inquire-statement.html](https://www.intel.com/content/www/us/en/docs/fortran-compiler/developer-guide-reference/2024-2/obtain-file-information-inquire-statement.html)

---

<div class="post-metadata">

**Author:** ![ricriv](https://avatars.discourse-cdn.com/v4/letter/r/f17d59/32.png) [@ricriv](https://fortran-lang.discourse.group/u/ricriv)\
**Post date:** [October 21, 2024, 8:09am UTC](https://fortran-lang.discourse.group/t/how-to-test-if-a-directory-exists/8731/14 "2024-10-21T08:09:35Z")

</div>

Thanks! This is a great, albeit non-portable, solution. It would be very nice if `INQUIRE(DIRECTORY=` would find its way into the standard.
