测试一个目录是否存在
我试图验证一个目录是否存在使用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编译器。
下面应该工作:
INQUIRE (DIRECTORY=dir, EXIST=ex [, DIRSPEC=dirspec] [, ERR=label] [, IOSTAT=i-var])
我没有这台机器上ifort所以我不能测试它。
附录:该代码原本与gfortran一起使用。 DIRECTORY
声明适用于ifort,但不适用于gfortran。
我不会推荐取决于非标准扩展名。有太多的情况,这意味着移植到另一个编译器时会遇到困难,这可能是意外需要的。 – 2012-03-02 08:57:52
我当然同意弗拉基米尔,但问题是,显然gfortran路线不起作用。对F95标准的快速浏览表明查询语句中的目录没有任何行为。如果我遗漏了一些东西(或者是以后的标准),请告诉我。 – Azrael3000 2012-03-02 09:20:38
但是在Linux上,目录只是具有目录登录的文件。也许ifort不喜欢尾随的'/ .'。 – 2012-03-02 13:23:10
Fortran标准95,2003年和2008年没有指定,如何查询应该把目录。根据我在Linux下的经验,gfortran将它们视为文件,ifort不会。目录声明是ifort的专有特性,因此应该避免。
最安全的方法是测试上述目录中的文件。
大多数情况下,检查目录是否存在以便在其中写入内容。我所做的只是创建目录。如果它已经存在没有问题。
CALL system("mkdir video")
CALL chdir("video")
CALL getcwd(path)
这里有一个子程序我经常使用 - 它使用你问条件:
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
,不知道它如何对待目录。
我有同样的问题。如果你想要一个独立于编译器的方式,你可以尝试在目录中打开一个小文件。开放式的语句允许代码跳转到一个特定的行(由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
请注意,这不是万无一失的,因为它假定“目录”的末尾加“ /“或”\“取决于正在使用的操作系统。
你如何区分目录不存在和不能删除/创建文件? – francescalus 2015-06-11 18:40:39
此代码不会,因此错误代码说不存在或不能写在那里。我不知道有什么方法可以说明差异。 – gordon 2015-06-12 19:45:27
另一个非便携式解决方案是让壳(猛砸,在这种情况下)做的工作:
call system('[[ ! -e docs ]] && mkdir docs')
这会创建一个目录。如果你不需要创建一个目录,你如何从中获得?这比“mkdir -p”更好吗? – 2015-08-06 10:36:21
我明白OP的问题/例子是他想创建一个目录。你是对的,'mkdir -p'几乎等于这个明确的测试。一个区别是,如果'docs'作为常规文件存在,则此方法不会引发错误消息。这可能会或可能不会有利。 – Frontier 2015-08-07 17:31:52
你可以使用C例程来测试文件:
C面(OK与ifort和gfortran在Win32和Linux 32/64)
#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)
优势:它适用于任何类型的文件,并提供类似的模式信息的附加件(读/写/执行权限)和创建时间。
作为解决方法,您也可以使用'mkdir -p'。 – 2012-03-02 13:10:06
你确定在第二次尝试之前使用查询吗?对于我的两个编译器(Oracle Solaris Studio,Gfortran)而言,它对我来说都很好。你也可以尝试'file ='。/ docs'',这也适用于我。 – 2012-03-02 13:19:52