语言自身没有列举文件夹的函数功能。
但不少编译器提供了这样的扩展,比如 Compaq 和 Intel Visual Fortran 提供的 GetFileInfoQQ 函数。
Subroutine DoWithWildcard(cWildcard,CallBack,iTotal)
Use DFLib,only:GetFileInfoQQ,GetLastErrorQQ,FILE$INFO,FILE$LAST,FILE$ERROR,FILE$FIRST,ERR$NOMEM,ERR$NOENT,FILE$DIR
Implicit None
Interface
Subroutine CallBack( FileName , loop )
Character(*),Intent(In) :: FileName
Integer,Intent(In) :: loop
End Subroutine CallBack
End Interface
Character*(*),Intent(In)::cWildcard
Integer,Intent(Out)::iTotal
TYPE (FILE$INFO) info
INTEGER(4)::Wildhandle,length,retInt
Wildhandle = FILE$FIRST
iTotal = 0
DO WHILE (.TRUE.)
length = GetFileInfoQQ(cWildCard,info,Wildhandle)
IF ((Wildhandle .EQ. FILE$LAST) .OR.(Wildhandle .EQ. FILE$ERROR)) THEN
SELECT CASE (GetLastErrorQQ())
CASE (ERR$NOMEM) !//内存不足
iTotal = - 1
Return
CASE (ERR$NOENT) !//碰到通配符序列尾
Return
CASE DEFAULT
iTotal = 0
Return
END SELECT
END IF
If ((info%permit.AND.FILE$DIR).Eq.0) then
Call CallBack( Trim(info.Name) , iTotal + 1 )
iTotal = iTotal + 1
End If
END DO
End Subroutine DoWithWildcard
!给你一个示范程序:
Program Main
Implicit None
External WriteName
Integer :: n
Call DoWithWildcard( '*.*' , WriteName , n )
If ( N >= 0 ) then
Write(*,*) '共' , N , '个文件!'
End If
End Program Main
!//这个程序需要自己编写,参数为两个,第一个参数为文件名,第二个参数为循环量。
Subroutine WriteName( FileName , loop )
Character(*),Intent(In) :: FileName
Integer,Intent(In) :: loop
Write(*,*) loop , FileName
End Subroutine WriteName
天河流纹石,回答的答案挺好,但是有bug。
网页链接这个链接就是他答案的来源,按照帖子说明,测试基本成功,稍有问题。其中bug怎么解决,刚刚给回了帖子。
再次感谢
zxcvbno
为了后来者用起来方便,把完整消除bug的代码如下所示。
! get_file_name.f90
! functions:
! get_file_name - entry point of console application.
!
!****************************************************************************
!
! program: get_file_name
!
! purpose: entry point for the console application.
!
!****************************************************************************
program get_file_name
implicit none
external writename
integer :: n
call dowithwildcard( '*.*' , writename , n )
if ( n >= 0 ) then
write(*,*) '共' , n , '个文件!'
end if
end program get_file_name
subroutine dowithwildcard(cwildcard,callback,itotal)
use dflib,only:getfileinfoqq,getlasterrorqq,file$info,file$last,file$error,file$first,err$nomem,err$noent,file$dir
implicit none
interface
subroutine callback( filename , loop )
character(*),intent(in) :: filename
integer,intent(in) :: loop
end subroutine callback
end interface
character*(*),intent(in)::cwildcard
integer,intent(out)::itotal
type (file$info) info
integer(4)::wildhandle,length,retint
character(100) :: lastname
wildhandle = file$first
itotal = 0
do while (.true.)
length = getfileinfoqq(cwildcard,info,wildhandle)
if ((wildhandle .eq. file$last) .or.(wildhandle .eq. file$error)) then
select case (getlasterrorqq())
case (err$nomem) !//内存不足
itotal = - 1
return
return
itotal = 0
return
end select
end if
if ((info%permit.and.file$dir).eq.0) then
if(trim(info.name) .eq. trim(lastname)) return
lastname = trim(info.name)
call callback( trim(info.name) , itotal + 1 )
itotal = itotal + 1
end if
end do
end subroutine dowithwildcard
subroutine writename( filename , loop )
character(*),intent(in) :: filename
integer,intent(in) :: loop
write(*,*) loop , filename
end subroutine writename
可以用system(dir *.* /b >info.log)再打开info.log文件,得到当前路径下所有的文件