VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 如 何 在VB 中 实 现 目 录 遍 历
发表评论(0)作者:张 易 平, 平台:VB6.0+Win98, 阅读:10848, 日期:2001-02-15
如 何 在VB 中 实 现 目 录 遍 历
中 兴 新 太 数 据 通 信 有 限 公 司
张 易 平
看 了 九 九 年 第 七 期E18 版 中《 子 目 录 级 文 件 查 询 的 实 现》 一 文, 为 便 于 读 者 方 便 使 用, 本 人 将 在VB 中 实 现 目 录 遍 历 需 要 注 意 的 地 方 及 代 码 提 供 给 读 者, 希 望 能 对 大 家 有 所 帮 助。 以 下 代 码 在PWIN97、VB6 下 测 试 通 过。

一、API 函 数 的 声 明、 自 定 义 数 据 类 型 及 常 量 的 定 义
注 意:API 函 数 的 声 明 应 在 应 用 程 序 的 代 码 模 块 中 进 行, 且 一 条 声 明 必 须 放 在 一 行 中注释:API 函 数 的 声 明
Public Declare Function FindFirstFile Lib
"kernel32" Alias "FindFirstFileA"
(ByVal lpFileName As String,
lpFindFileData As WIN32_FIND_DATA) As Long
Public Declare Function FindNextFile Lib
"kernel32" Alias "FindNextFileA"
(ByVal hFindFile As Long, lpFindFileData
As WIN32_FIND_DATA) As Long
Public Declare Function FindClose Lib
"kernel32" (ByVal hFindFile As Long) As Long

注释:最大路径长度和文件属性常量的定义
Public Const MAX_PATH = 260
Public Const FILE_ATTRIBUTE_ARCHIVE = &H20
Public Const FILE_ATTRIBUTE_COMPRESSED = &H800
Public Const FILE_ATTRIBUTE_DIRECTORY = &H10
Public Const FILE_ATTRIBUTE_HIDDEN = &H2
Public Const FILE_ATTRIBUTE_NORMAL = &H80
Public Const FILE_ATTRIBUTE_READONLY = &H1
Public Const FILE_ATTRIBUTE_SYSTEM = &H4
Public Const FILE_ATTRIBUTE_TEMPORARY = &H100

注释:自定义数据类型FILETIME和WIN32_FIND_DATA的定义
Public Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Public Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type

二、 去 掉 固 定 长 度 字 符 串 右 边 的NULL 字 符(ASCII 值 为0) 和SPACE 字 符(ASCII 值 为32)
由 于 数 据 类 型WIN32_FIND_DATA 的cFileName 元 素 为 定 长 数 据 类 型 且 在 执 行 函 数FindFirstFile 和FindNextFile 后 会 有NULL 字 符, 因 此 需 去 掉 其 中 的 无 效 字 符。
Public Function fDelInvaildChr
(str As String) As String
On Error Resume Next
For i = Len(str) To 1 Step -1
  If Asc(Mid(str, i, 1)) < >
   0 And Asc(Mid(str, i, 1)) <> 32 Then
   fDelInvaildChr = Left(str, i)
   Exit For
  End If
Next
End Function

三、 遍 历 主 函 数
参 数 说 明:
strPathName要遍历的目录
objList    使用VB的内部控
           件ListBox来存放遍历得到的路径,之所以
           不使用字符串数组是因为数组大小不好定义

Public Sub sDirTraversal
(ByVal strPathName As String, ByRef objList As ListBox)
Dim sSubDir(200) As String
      注释:存放当前目录下的子目录,下标可根据需要调整
Dim iIndex As Integer
         注释:子目录数组下标
Dim i As Integer
           注释:用于循环子目录的查找

Dim lHandle As Long
       注释:FindFirstFileA的句柄
Dim tFindData As WIN32_FIND_DATA 注释:
Dim strFileName As String     注释:文件名

On Error Resume Next
注释:初始化变量
i = 1
iIndex = 0
tFindData.cFileName =
  ""  注释:初始化定长字符串

lHandle = FindFirstFile
  (strPathName & "\*.*", tFindData)
If lHandle = 0 Then    注释:查询结束或发生错误
  Exit Sub
End If
strFileName = fDelInvaildChr(tFindData.cFileName)
If tFindData.dwFileAttributes = &H10 Then   注释:目录
  If strFileName <> "." And strFileName <> ".." Then
   iIndex = iIndex + 1
   sSubDir(iIndex) = strPathName
   & "\" & strFileName  注释:添加到目录数组
  End If
Else
  objList.AddItem strPathName
   & "\" & strFileName
End If
注释:循环查找下一个文件,直到结束
Do While True
  tFindData.cFileName = ""
  If FindNextFile(lHandle, tFindData)
  = 0 Then  注释:查询结束或发生错误
   FindClose (lHandle)
   Exit Do
  Else
   strFileName = fDelInvaildChr
  (tFindData.cFileName)
    If tFindData.dwFileAttributes = &H10 Then
    If strFileName <> "." And strFileName <> ".." Then
     iIndex = iIndex + 1
     sSubDir(iIndex) = strPathName
     & "\" & strFileName  注释:添加到目录数组
    End If
   Else
    objList.AddItem strPathName & "\" & strFileName
   End If
  End If
Loop
注释:如果该目录下有目录,则根据目录数组递归遍历
If iIndex > 0 Then
  For i = 1 To iIndex
   sDirTraversal sSubDir(i), objList
  Next
End If
End Sub

利 用 以 上 遍 历 方 法, 读 者 可 以 根 据 数 据 类 型WIN32_FIND_DATA 的dwFileAttributes、ftCreationTime、ftLastAccessTime、ftLastWriteTime 元 素 来 扩 充 文 件 查 询 功 能( 按 文 件 属 性、 创 建 日 期、 最 后 修 改 日 期、 最 后 访 问 日 期 等 不 同 条 件 的 查 询)。