测试目录是否存在

时间:2012-03-01 19:48:50

标签: fortran fortran90 intel-fortran

我正在尝试使用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,如果我执行此代码两次,则会收到错误消息

  

无法制作dir,文件已存在

如果我使用:

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

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

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

7 个答案:

答案 0 :(得分:5)

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

最安全的是测试上述目录中的文件。

答案 1 :(得分:4)

以下内容应该有效:

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

答案 2 :(得分:3)

大多数情况下,会检查目录是否存在,以便在其中写入内容。我所做的只是创建目录。如果已经存在则没有问题。

     CALL system("mkdir video")
     CALL chdir("video")
     CALL getcwd(path)

答案 3 :(得分: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)

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

答案 4 :(得分:0)

这是我经常使用的子程序 - 它使用您询问的条件:

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并且不知道它如何处理目录。

答案 5 :(得分: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

请注意,这不是万无一失的,因为它被认为是&#34; dir&#34;有尾随&#34; /&#34;或&#34; \&#34;取决于使用的操作系统。

答案 6 :(得分:0)

另一个不可移植的解决方案是让shell(在本例中为Bash)完成工作:

parties-list.ng.html