如何在VB中實現目錄遍歷
一、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 元 素 來 擴 充 文 件 查 詢 功 能( 按 文 件 屬 性、 創 建 日 期、 最 后 修 改 日 期、 最 后 訪 問 日 期 等 不 同 條 件 的 查 詢)。
完 整 代 碼 :
'''''''''''''''''''''''''''''''''''''''''''
'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)函數
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
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