8

我正在尝试使用 Fortan90 验证目录是否存在。在我发现的各种网站上:

logical :: dir_e
inquire(file='./docs/.', exist=dir_e)

if ( dir_e ) then
  write(*,*) "dir exists!"
else
  ! workaround: it calls an extern program...
  call system('mkdir docs')
end if

但是,inquire返回False目录是否存在,如果我执行此代码两次,我会收到一条错误消息

无法制作目录,文件已存在

如果我使用:

inquire(file='./docs/test', exist=dir_e)

使用现有文件测试,inquire返回true.

如何检查目录是否存在?我正在使用 ubuntu 11.04 和 ifort 编译器。

4

7 回答 7

7

Fortran 标准 95、2003 和 2008 未指定查询应如何处理目录。根据我在 Linux 下的经验,gfortran 将它们视为文件,ifort 没有。目录语句是 ifort 的专有功能,因此应避免使用。

最安全的方法是测试所述目录中的文件。

于 2014-02-18T08:54:11.467 回答
5

以下应该有效:

INQUIRE (DIRECTORY=dir, EXIST=ex [, DIRSPEC=dirspec] [, ERR=label] [, IOSTAT=i-var] )

我在这台机器上没有 ifort,所以我无法测试它。

附录:最初发布的代码适用于 gfortran。该DIRECTORY语句适用于 ifort,但不适用于 gfortran。

如果需要更多信息检查: http: //software.intel.com/sites/products/documentation/hpc/compilerpro/en-us/fortran/win/compiler_f/lref_for/source_files/rfinquir.htm#rfinquir

于 2012-03-01T20:16:28.420 回答
3

大多数时候,检查目录是否存在以便在其中写一些东西。我所做的只是创建目录。如果它已经存在,则没有问题。

     CALL system("mkdir video")
     CALL chdir("video")
     CALL getcwd(path)
于 2014-02-27T20:52:58.027 回答
2

这是我经常使用的一个子程序——它使用你询问的条件:

subroutine create_directory( newDirPath )
    ! Author:  Jess Vriesema
    ! Date:    Spring 2011
    ! Purpose: Creates a directory at ./newDirPath

    implicit none

    character(len=*), intent(in) :: newDirPath
    character(len=256)           :: mkdirCmd
    logical                      :: dirExists

    ! Check if the directory exists first
!   inquire( file=trim(newDirPath)//'/.', exist=dirExists )  ! Works with gfortran, but not ifort
    inquire( directory=newDirPath, exist=dirExists )         ! Works with ifort, but not gfortran


    if (dirExists) then
!      write (*,*) "Directory already exists: '"//trim(newDirPath)//"'"
    else
        mkdirCmd = 'mkdir -p '//trim(newDirPath)
        write(*,'(a)') "Creating new directory: '"//trim(mkdirCmd)//"'"
        call system( mkdirCmd )
    endif
end subroutine create_directory

根据您使用的编译器,您必须决定哪些条件适合您。

不幸的是,我无权访问nagfor也不知道它如何处理目录。

于 2014-07-10T02:54:45.747 回答
2

您可以使用 C 例程来测试文件:

C 端(在 Win32 和 Linux 32/64 上使用 ifort 和 gfortran 可以)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#if defined(_WIN32) && defined(__INTEL_COMPILER)
#  include "dirent_windows.h"
#else
#  include <dirent.h>
#endif

void file_info(const char*filename,int*mode,int*exist,int*time){
  int k;
  struct stat buf;
  k=stat(filename,&buf);
  if(k != 0) {
    *mode=0;
    *exist=0;
    *time=0;
  }else{
    *mode=buf.st_mode;
    if(*mode == 0) *exist=0; else *exist=1;
    *time=buf.st_mtime;
  }
}

Fortran 方面:

MODULE file

  USE iso_c_binding

  INTERFACE
    SUBROUTINE file_info(filename,mode,exist,time) BIND(C,name="file_info")
      USE iso_c_binding
      CHARACTER(kind=C_CHAR),INTENT(in) :: filename(*)
      INTEGER(C_INT),INTENT(out) :: mode,exist,time
    END SUBROUTINE
  END INTERFACE

END MODULE

如何在 Fortran 例程中使用:

..
use file
use iso_c_binding
...
integer(c_int) :: mode,exist,time
...
call file_info("./docs"//char(0),mode,exist,time)

优点:它适用于任何类型的文件,并提供额外的信息,如模式(读/写/执行权限)和创建时间。

于 2015-08-07T09:00:03.947 回答
1

另一个不可移植的解决方案是让外壳(在这种情况下为 Bash)完成工作:

call system('[[ ! -e docs ]] && mkdir docs')
于 2015-08-06T01:21:00.207 回答
0

我有同样的问题。如果您想要一种独立于编译器的方式来执行此操作,您可以尝试在目录中打开一个小文件。如果 open 语句失败,open 语句允许代码跳转到特定行(由 err= 指定):

! Tests whether the directory exists
subroutine checkdir(dir)
       implicit none
       character(len=*), intent(in) :: dir
       integer :: unitno

       ! Test whether the directory exists
       open(newunit=unitno,file=trim(dir)//'deleteme.txt',status='replace',err=1234)
       close (unitno)
       return

       ! If doesn't exist, end gracefully
1234   write(*,*) 'Data directory, '//trim(dir)//' does not exist or could not write there!'
       STOP

end subroutine

请注意,这并非万无一失,因为根据所使用的操作系统,假定“dir”具有尾随“/”或“\”。

于 2015-06-11T18:00:01.390 回答