VB6遍历目录(文件夹和文件)

日期:2023年2月27日
作者:Commas
签名:(ง •_•)ง 积跬步以致千里,积小流以成江海……
注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^
1.01365 = 37.7834;0.99365 = 0.0255
1.02365 = 1377.4083;0.98365 = 0.0006



在这里插入图片描述


一、目录、文件夹、文件以及路径的概念

在学习中,工作中,我们经常会说遍历一下当前目录咯。但是一旦被问到这个目录到底是什么的时候,明明我们感觉自己知道是什么,却又说不清楚到底是什么。没关系,接下来我们来了解下,下次就可以说清楚啦……

中文名英文名说明
目录directory一系列文件和文件夹的集合
文件夹folder用来存放文件和文件夹的容器
文件file用来存储信息的单个数据单元(文本、图像、声音等等)
路径path用于定位文件的路径

从上表可以看出,目录和文件夹意思差不多……

实际上目录DOS操作系统时期的称呼,而Windows操作系统时期的称呼为文件夹

严格来说,目录不是文件夹,因为目录映射到存储介质上的物理位置,而文件夹不一定,例如桌面上的文件夹。

现在我们回过头来看“遍历一下当前目录”的含义,实际上就是遍历一系列的文件与文件夹。

这些文件与文件夹和当前路径有着千丝万缕的关系,因此我们会觉得当前目录的感觉又有点侧重于路径,不过它绝不是路径。

二、聊一聊Dir函数

在这里插入图片描述

语法:

Function Dir([PathName], [Attributes As VbFileAttribute = vbNormal]) As String

attributes 参数的设置可为:

常数描述
vbNormal0(缺省) 指定没有属性的文件。
vbReadOnly1指定无属性的只读文件
vbHidden2指定无属性的隐藏文件
VbSystem4指定无属性的系统文件
vbVolume8指定卷标文件;如果指定了其它属性,则忽略vbVolume
vbDirectory16指定无属性文件及其路径和文件夹。

说明:

  • DirVBA.FileSystem 的成员,返回一个 String,用以表示一个文件名、目录名或文件夹名称,它必须与指定的模式或文件属性、或磁盘卷标相匹配;
  • pathname 可选参数。用来指定文件名的字符串表达式,可能包含目录或文件夹、以及驱动器。如果没有找到 pathname,则会返回零长度字符串 ("");
  • attributes 可选参数。常数或数值表达式,其总和用来指定文件属性。如果省略,则会返回匹配 pathname 但不包含属性的文件。

用法:

  • 在第一次调用 Dir 函数时,必须指定 pathname,否则会产生错误。如果也指定了文件属性,那么就必须包括 pathname
  • Dir 会返回匹配 pathname 的第一个文件名。若想得到其它匹配 pathname 的文件名,再一次调用 Dir,且不要使用参数。如果已没有合乎条件的文件,则 Dir 会返回一个零长度字符串 ("")。一旦返回值为零长度字符串,并要再次调用 Dir 时,就必须指定 pathname,否则会产生错误。不必访问到所有匹配当前 pathname 的文件名,就可以改变到一个新的 pathname 上。但是,不能以递归方式来调用 Dir 函数。以 vbDirectory 属性来调用 Dir 不能连续地返回子目录。

提示:

  • 由于文件名并不会以特别的次序来返回,所以可以将文件名存储在一个数组中,然后再对这个数组排序;
  • 不能以递归方式来调用 Dir 函数(注意,这是重点,画起来哈

三、Dir遍历目录的示例

在操作之前,我们先看看当前目录结构,这次就在命令行看吧。(想快速了解命令行如何使用,请看我CSDN中的另外一篇博客《Windows中的CMD不需要死记硬背》

首先,我们得了解怎么用tree来查看当前目录树,执行tree /?

D:\traversingByDir>tree /?
以图形显示驱动器或路径的文件夹结构。       

TREE [drive:][path] [/F] [/A]

   /F   显示每个文件夹中文件的名称。       
   /A   使用 ASCII 字符,而不使用扩展字符。

然后,我们使用tree /F查看当前目录树结构,如下所示

D:\traversingByDir>tree /F
文件夹 PATH 列表
卷序列号为 277B-1704
D:.
│  clsUtils.bas
│  frmMain.frm
│  MSSCCPRJ.SCC
│  traversingByDir.vbp
│  traversingByDir.vbw
│
└─父
    │  11.txt
    │
    └─子
        │  22.txt
        │
        └─孙
                33.txt

(3-1)Dir直接遍历

Public Sub UnTraversalDirs(ByVal sPath As String)
On Error Resume Next
'函数说明:遍历当前目录,仅打印出当前目录的文件夹名称和文件名称
'创建作者:Commas
'创建时间:2022-02-24
'修改时间:
'------数据格式说明------
'sPath:查询路径
'------数据格式说明------
    Dim strTemp As String
    strTemp = Dir(sPath & "\*.*", vbDirectory + vbNormal + vbArchive + vbHidden + vbReadOnly + vbSystem)
    Do Until strTemp = ""
        Debug.Print strTemp
        strTemp = Dir()
    Loop
    
End Sub

调用代码:

Call UnTraversalDirs(App.Path)

输出结果:

.
..
clsUtils.bas
frmMain.frm
MSSCCPRJ.SCC
traversingByDir.vbp
traversingByDir.vbw
父

结果说明:

打印内容说明
.特定的目录项,表示当前目录
..特定的目录项,表示上级目录
clsUtils.bas文件名称
frmMain.frm文件名称
MSSCCPRJ.SCC文件名称
traversingByDir.vbp文件名称
traversingByDir.vbw文件名称
文件夹名称

由此,我们有两点结论:

  • Dir只能遍历当前目录,无法遍历子孙目录;
  • ...是特定的目录项,应该排除...的结果;

故,可以修改为:

Public Sub UnTraversalDirs(ByVal sPath As String)
On Error Resume Next
'函数说明:遍历当前目录,仅打印出当前目录的文件夹名称和文件名称
'创建作者:Commas
'创建时间:2022-02-24
'修改时间:
'------数据格式说明------
'sPath:查询路径
'------数据格式说明------
    Dim strTemp As String
    strTemp = Dir(sPath & "\*.*", vbDirectory + vbNormal + vbArchive + vbHidden + vbReadOnly + vbSystem)
    Do Until strTemp = ""
        If strTemp <> "." And strTemp <> ".." Then
            Debug.Print strTemp
        End If
        
        strTemp = Dir()
    Loop
    
End Sub

(3-2)第一次封装:Dir递归遍历

在开始之前,我们先封装两个函数,一个用来判断是否是文件夹,另一个是路径拼接,如下所示:

Public Function IsDir(ByVal sPath As String) As Boolean
On Error Resume Next
'函数说明:判断是否为文件夹
'创建作者:Commas
'创建时间:2022-02-24
'修改时间:
'------数据格式说明------
'sPath:查询路径
'------数据格式说明------
    If (VBA.GetAttr(sPath) And vbDirectory) <> 0 Then
        IsDir = True
    Else
        IsDir = False
    End If
End Function

Public Function PathJoin(ByVal sPath As String, ByVal sName As String) As String
On Error Resume Next
'函数说明:路径合并
'创建作者:Commas
'创建时间:2022-02-24
'修改时间:
'------数据格式说明------
'sPath:查询路径
'sName:拼接名称
'------数据格式说明------
    If sName <> "" Then
        PathJoin = sPath & "\" & sName
    Else
        PathJoin = sPath
    End If
End Function

我们将(3-1)中所说的UnTraversalDirs(ByVal sPath As String)遍历当前目录,封装成ListDir(ByVal sPath As String, ByRef clnDir As Collection),用来执行递归调用,这样就可以比较完美的解决Dir无法递归的问题。这个函数也有点抄作业的感觉,抄Python的内置函数os.listdir(path)。如感兴趣,可以看我的另一篇博客《python3遍历目录的三种方法浅谈》

ListDir:返回查询目录的遍历结果

Public Sub ListDir(ByVal sPath As String, ByRef clnDir As Collection)
On Error Resume Next
'函数说明:返回查询目录的遍历结果
'创建作者:Commas
'创建时间:2022-02-24
'修改时间:
'------数据格式说明------
'sPath:查询路径
'clnDir:查询返回结果,以集合返回
'------数据格式说明------
    Dim strTemp As String, cPath As String
    strTemp = Dir(sPath & "\*.*", vbDirectory + vbNormal + vbArchive + vbHidden + vbReadOnly + vbSystem)
        
    Do Until strTemp = ""
        cPath = PathJoin(sPath, strTemp)
        If IsDir(cPath) Then
            'floder
            If strTemp = "." Or strTemp = ".." Then
                'pass
                '目录在计算机的文件系统中也是文件,.和 .. 在目录文件中标识特定的目录项
                'linux下当前目录和上级目录
            Else
                clnDir.Add strTemp
            End If
        Else
            'file
            
            clnDir.Add strTemp
        End If
        
        strTemp = Dir()
    Loop
End Sub

调用代码:

Dim clnDir As Collection, i As Long
Set clnDir = New Collection
Call ListDir(App.Path, clnDir)
For i = 1 To clnDir.Count
    Debug.Print clnDir(i)
Next i

输出结果:

clsUtils.bas
frmMain.frm
MSSCCPRJ.SCC
traversingByDir.vbp
traversingByDir.vbw
父

接下来我们来递归调用ListDir,打印出查询的所有目录结果:

  • 封装
Public Sub TraversalDirs(sPath)
On Error Resume Next
'函数说明:递归遍历当前目录,包括子孙目录
'创建作者:Commas
'创建时间:2022-02-24
'修改时间:
'------数据格式说明------
'sPath:查询路径
'------数据格式说明------
    Dim clnDir As New Collection, i As Long
    Dim cPath As String
    
    Call ListDir(sPath, clnDir)
    For i = 1 To clnDir.Count
        Debug.Print clnDir(i)
        cPath = PathJoin(sPath, clnDir(i))
        If IsDir(cPath) Then
            Call TraversalDirs(cPath)
        End If
    Next i
End Sub
  • 调用代码
Call TraversalDirs(App.Path)
  • 输出结果
clsUtils.bas
frmMain.frm
MSSCCPRJ.SCC
traversingByDir.vbp
traversingByDir.vbw
父
11.txt
子
22.txt
孙
33.txt

(3-3)第二次封装:Dir递归遍历

ListAllDir:获取路径下的所有目录(文件夹目录+文件目录),即遍历路径下所有文件夹和文件,返回值为目录集合。

Public Function ListAllDir(ByVal sPath As String, ByRef clnDir As Collection) As Collection
On Error Resume Next
'函数说明:获取路径下的所有目录(文件夹目录+文件目录),即遍历路径下所有文件夹和文件,返回值为目录集合。
'创建作者:Commas
'创建时间:2022-02-24
'修改时间:
'------数据格式说明------
'sPath:查询路径
'------数据格式说明------
    Dim clnFdDir As New Collection, i As Long
    Dim strTemp As String, cPath As String
    
    strTemp = Dir(sPath & "\*.*", vbDirectory + vbNormal + vbArchive + vbHidden + vbReadOnly + vbSystem)
        
    Do Until strTemp = ""
        cPath = PathJoin(sPath, strTemp)
        
        If IsDir(cPath) Then
            'folder
            If strTemp = "." Or strTemp = ".." Then
                'pass
                '目录在计算机的文件系统中也是文件,.和 .. 在目录文件中标识特定的目录项
                'linux下当前目录和上级目录
            Else
                clnFdDir.Add cPath
                clnDir.Add cPath
            End If
        Else
            'file
            
            'Debug.Print strTemp
            clnDir.Add cPath
        End If
        
        strTemp = Dir()
    Loop
    
    
    If clnFdDir.Count > 0 Then
        For i = 1 To clnFdDir.Count
            'Debug.Print i, clnFdDir(i)
            Call ListAllDir(clnFdDir(i), clnDir)
        Next i
    End If
    
End Function

  • 调用代码
    Dim clnAllDir As Collection, i As Long

    Set clnAllDir = New Collection
    Call ListAllDir(App.Path, clnAllDir)
    For i = 1 To clnAllDir.Count
        Debug.Print clnAllDir(i)
    Next i
  • 输出结果
D:\traversingByDir\clsUtils.bas
D:\traversingByDir\frmMain.frm
D:\traversingByDir\MSSCCPRJ.SCC
D:\traversingByDir\traversingByDir.vbp
D:\traversingByDir\traversingByDir.vbw
D:\traversingByDir\父
D:\traversingByDir\父\11.txt
D:\traversingByDir\父\子
D:\traversingByDir\父\子\22.txt
D:\traversingByDir\父\子\孙
D:\traversingByDir\父\子\孙\33.txt

我的微信公众号【会飞的小猴子】,等你来关注哦 ^ - ^


1、《What is the difference between a directory and a folder?》
2、《极客教程-Python os.scandir()方法》
3、《python3遍历目录的三种方法浅谈》


版权声明:本文为博主原创文章,如需转载,请给出:
原文链接:https://blog.csdn.net/qq_35844043/article/details/129198516

VB,可以使用API函数来遍历指定驱动器或目录文件。首先,我们需要声明一些需要使用的API函数。 1. 声明函数:需要使用FindFirstFile、FindNextFile和FindClose函数来进行文件搜索。 Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long 2. 声明数据结构:需要使用WIN32_FIND_DATA结构体来存储搜索到的文件信息。 Private Type WIN32_FIND_DATA dwFileAttributes As Long ftCreationTime As Currency ftLastAccessTime As Currency ftLastWriteTime As Currency nFileSizeHigh As Long nFileSizeLow As Long dwReserved0 As Long dwReserved1 As Long cFileName As String * 260 cAlternate As String * 14 End Type 接下来,我们可以编写一个过程来进行文件搜索并遍历。 Private Sub GetFiles(ByVal path As String) Dim hSearch As Long Dim findData As WIN32_FIND_DATA '添加路径分隔符 If Right$(path, 1) <> "\" Then path = path & "\" End If '开始搜索 hSearch = FindFirstFile(path & "*", findData) If hSearch <> -1 Then Do '忽略隐藏和系统文件夹 If (findData.dwFileAttributes And vbHidden) = 0 And (findData.dwFileAttributes And vbSystem) = 0 Then '找到了文件,处理文件 Debug.Print findData.cFileName End If Loop While FindNextFile(hSearch, findData) <> 0 FindClose hSearch End If End Sub 在这个过程,我们首先根据路径和通配符 "*" 调用FindFirstFile函数来搜索第一个文件,然后使用FindNextFile函数来继续搜索下一个文件,直到没有文件可搜索为止。在每一次搜索到文件时,我们可以进行相应的处理,这里只是简单地输出文件名。 例如,我们可以调用以下代码来遍历D盘根目录文件。 GetFiles "D:\" 这样就可以遍历D盘根目录的所有文件,并输出文件名。当然,你可以根据自己的需求对搜索到的文件进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Commas.KM

码路共同进步,感恩一路有您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值