用Dir是可以实现递归调用的,但必须用点特殊的技巧:在遍历某个文件夹时,如果遇到子文件夹,不要立刻递归调用,要先把它存入一个数组中,当整个文件夹遍历完毕并处理完所有文件后(换句话说就是当本次的所有Dir函数都执行完毕后),再通过循环对数组中的每个子文件夹进行递归调用,这样就不会对Dir函数的运行造成干扰了。
Sub ssdir(p As String)Dim d() As String, f As String, i As Long
f = Dir(p & "\*.*", vbDirectory + vbNormal + vbArchive + vbHidden + vbReadOnly + vbSystem)
Do Until f = ""
If (GetAttr(p & "\" & f) And vbDirectory) <> 0 Then '如果是子文件夹
ReDim Preserve d(i)
d(i) = f '子文件夹存入数组
i = i + 1
Else
'对文件的处理这里略
End If
f = Dir
Loop
For i = 0 To UBound(d)
ssdir p & "\" & d(i) '递归调用
Next
End Sub
首先一个基本概念要先搞清楚:在FAT32文件系统中,一个文件夹内放的文件及子文件夹数量的上限是65534个(如果用了长文件名,这个数量会减少),而在NTFS文件系统中,这个值就变为4G-1即40多亿,几乎是无限了。你说的15万个文件的文件夹,那很显然是NTFS系统的。
其次,VB6是上世纪末出生的老古董软件,是32位的程序开发语言,它诞生的时候,FAT32是当时最常见也是最先进的文件系统,所以VB6也是按FAT32来 *** 作文件的,再考虑到要兼容长文件名,所以VB6本身的控件和函数在一个文件夹中所能 *** 作的文件数量限制是32767个(折半)。
因此,你这15万个文件的文件夹是无法用VB本身自带的控件或函数来遍历的,只能使用第三方控件或组件,比如大名鼎鼎的FSO:
Dim fso As Object, fd As Object, f As ObjectSet fso = CreateObject("Scripting.FileSystemObject")
Set fd = fso.GetFolder("要处理的文件夹全路径名写在这")
For Each f In fd.Files
'这里是对遍历出的每个文件进行 *** 作
'其中f.Name是文件名,f.Path是文件路径,
'f.Size是文件大小,f.Type是文件类型,等等
'为了防止卡顿,可以在这个循环里用下面这行:
'DoEvents
Next
Set fd = Nothing
Set fso = Nothing
我没测试,因为我没有这么多文件的文件夹。
如果这个方法也不行,那就只能用API了。
楼主还是先搞清楚递归是咋回事吧...递归是指某过程直接或者间接的调用其自身的 *** 作...
再看看MSDN中对DIR函数的解释
Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。不必访问到所有匹配当前 pathname 的文件名,就可以改变到一个新的 pathname 上。但是,不能以递归方式来调用 Dir 函数。以 vbDirectory 属性来调用 Dir 不能连续地返回子目录。
由此可见,当你第二次调用dir(无参数时),系统会使用你第一次调用dir时的参数(第一次使用必须指定参数),如果无符合条件的文件,则返回空字符
假设你设计的递归过程是 ShowDir
那么,当首次执行Dir(C:\*.*)的时候,会返回A,然后调用一下自身递归C:\A\*.*
直到无子目录,才会返回第一次执行的ShowDir,然后继续返回下个文件夹B
说这么多不直到你是否能理解....
最好你找个递归的例子,然后设置断点,去看调用堆栈,就明白了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)