2012-03-01 39 views
5

Tôi đang cố xác minh rằng thư mục tồn tại bằng Fortan90. Trên các trang web khác nhau tôi thấy:Kiểm tra xem một thư mục có tồn tại hay không

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 

Tuy nhiên, inquire lợi nhuận False hay không thư mục tồn tại và nếu tôi thực thi mã này hai lần, tôi nhận được một thông báo lỗi

không thể làm cho dir, tập tin đã tồn tại

Nếu tôi sử dụng:

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

với thử nghiệm tệp hiện có, inquire trả về true.

Làm cách nào để kiểm tra sự tồn tại của thư mục? Tôi đang sử dụng ubuntu 11.04 và trình biên dịch ifort.

+3

Giải pháp thay thế bạn cũng có thể sử dụng 'mkdir -p'. –

+0

Bạn có chắc chắn rằng bạn sử dụng yêu cầu trước lần thử thứ hai không? Nó làm việc cho tôi tốt cho cả hai trình biên dịch của tôi (Oracle Solaris Studio, Gfortran). Bạn cũng có thể thử 'file = './Docs'' chỉ, điều đó cũng phù hợp với tôi. –

Trả lời

5

Sau đây nên làm việc:

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

Tôi không có ifort trên máy tính này vì vậy tôi không thể kiểm tra nó.

Phụ lục: Mã được đăng ban đầu hoạt động với gfortran. Câu lệnh DIRECTORY hoạt động với ifort nhưng không hoạt động với gfortran.

Và trong trường hợp để biết thêm thông tin kiểm tra: http://software.intel.com/sites/products/documentation/hpc/compilerpro/en-us/fortran/win/compiler_f/lref_for/source_files/rfinquir.htm#rfinquir

+0

Tôi sẽ không khuyên bạn nên tùy thuộc vào tiện ích mở rộng không chuẩn. Có quá nhiều trường hợp, điều đó có nghĩa là khó khăn khi chuyển sang trình biên dịch khác, điều này có thể cần thiết bất ngờ. –

+0

Tôi tất nhiên tôi đồng ý với Vladimir, nhưng vấn đề là dường như tuyến đường gfortran không hoạt động. Nhìn lướt qua tiêu chuẩn F95 cho thấy không có hành vi nào cho các thư mục trong câu lệnh inquire. Nếu tôi bị mất một cái gì đó (hoặc nó đã được thêm vào một tiêu chuẩn sau này) cho tôi biết. – Azrael3000

+1

Nhưng trên các thư mục linux chỉ là các tập tin với một dấu hiệu thư mục trên. Có lẽ ifort không thích dấu '/ .'. –

2

Các Fortran chuẩn 95, 2003 và 2008 không chỉ định, làm thế nào tìm hiểu nên đối xử với thư mục. Từ kinh nghiệm của tôi dưới Linux, gfortran coi chúng là tệp, ifort thì không. Các tuyên bố thư mục là một tính năng độc quyền của ifort và do đó nên tránh.

Cách an toàn nhất là kiểm tra tệp trong thư mục đã nói.

3

Hầu hết thời gian, một lần kiểm tra xem thư mục có tồn tại để viết thứ gì đó trong đó hay không. Những gì tôi làm chỉ là tạo thư mục. Nếu nó đã tồn tại thì không có vấn đề gì.

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

Dưới đây là một chương trình con tôi sử dụng thường - nó sử dụng có điều kiện bạn hỏi về:

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 

Tùy thuộc vào trình biên dịch bạn sử dụng, bạn sẽ phải quyết định những điều kiện phù hợp với bạn.

Rất tiếc, tôi không có quyền truy cập vào nagfor và không biết cách xử lý thư mục.

0

Tôi gặp vấn đề tương tự. Nếu bạn muốn một trình biên dịch độc lập cách làm điều này, bạn có thể thử mở một tệp nhỏ trong thư mục. Những tuyên bố mở cho phép mã để chuyển đến một dòng cụ thể (theo quy định của err =) nếu tuyên bố mở thất bại:

! 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 

Lưu ý rằng điều này là không đơn giản, vì nó được giả định "dir" có dấu "/"hoặc" \ "tùy thuộc vào hệ điều hành đang được sử dụng.

+0

Làm thế nào để bạn biết sự khác biệt giữa thư mục không tồn tại và không thể xóa/tạo tệp? – francescalus

+0

Mã này không, do đó mã lỗi nói không tồn tại hoặc không thể viết ở đó. Tôi không biết cách nào để nói sự khác biệt. – gordon

0

Một giải pháp không cầm tay là để cho vỏ (Bash, trong trường hợp này) làm việc:

call system('[[ ! -e docs ]] && mkdir docs') 
+0

Việc này tạo một thư mục. Làm thế nào để bạn nhận được từ này nếu một thư mục tồn tại nếu bạn không cần phải được tạo ra? Làm thế nào là tốt hơn chỉ là 'mkdir -p'? –

+0

Tôi hiểu câu hỏi/ví dụ của OP là anh ta muốn tạo một thư mục. Bạn đúng, 'mkdir -p' gần như tương đương với bài kiểm tra rõ ràng này. Một khác biệt là nếu 'docs' tồn tại dưới dạng tệp thông thường, phương thức này không đưa ra thông báo lỗi. Điều đó có thể hoặc có thể không thuận lợi. – Frontier

1

Bạn có thể sử dụng thói quen C để kiểm tra các tập tin:

C bên (OK với ifort và gfortran trên Win32 và 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 phụ:

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 

Làm thế nào để sử dụng trong một thói quen Fortran:

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

Ưu điểm: nó hoạt động cho bất kỳ loại tập tin và cung cấp thông tin bổ sung như chế độ (đọc/ghi/thực hiện phép) và thời gian sáng tạo.

Các vấn đề liên quan