一、API函数的声明、自定义数据类型及常量的定义 ----注意:API函数的声明应在应用程序的代码模块中进行,且一条声明必须放在一行中'API函数的声明 PublicDeclareFunctionFindFirstFileLib "kernel32"Alias"FindFirstFileA" (ByVallpFileNameAsString, lpFindFileDataAsWIN32_FIND_DATA)AsLong PublicDeclareFunctionFindNextFileLib "kernel32"Alias"FindNextFileA" (ByValhFindFileAsLong,lpFindFileData AsWIN32_FIND_DATA)AsLong PublicDeclareFunctionFindCloseLib "kernel32"(ByValhFindFileAsLong)AsLong
'最大路径长度和文件属性常量的定义 PublicConstMAX_PATH=260 PublicConstFILE_ATTRIBUTE_ARCHIVE=&H20 PublicConstFILE_ATTRIBUTE_COMPRESSED=&H800 PublicConstFILE_ATTRIBUTE_DIRECTORY=&H10 PublicConstFILE_ATTRIBUTE_HIDDEN=&H2 PublicConstFILE_ATTRIBUTE_NORMAL=&H80 PublicConstFILE_ATTRIBUTE_READONLY=&H1 PublicConstFILE_ATTRIBUTE_SYSTEM=&H4 PublicConstFILE_ATTRIBUTE_TEMPORARY=&H100
'自定义数据类型FILETIME和WIN32_FIND_DATA的定义 PublicTypeFILETIME dwLowDateTimeAsLong dwHighDateTimeAsLong EndType
PublicTypeWIN32_FIND_DATA dwFileAttributesAsLong ftCreationTimeAsFILETIME ftLastAccessTimeAsFILETIME ftLastWriteTimeAsFILETIME nFileSizeHighAsLong nFileSizeLowAsLong dwReserved0AsLong dwReserved1AsLong cFileNameAsString*MAX_PATH cAlternateAsString*14 EndType
二、去掉固定长度字符串右边的NULL字符(ASCII值为0)和SPACE字符(ASCII值为32) ----由于数据类型WIN32_FIND_DATA的cFileName元素为定长数据类型且在执行函数FindFirstFile和FindNextFile后会有NULL字符,因此需去掉其中的无效字符。 PublicFunctionfDelInvaildChr (strAsString)AsString OnErrorResumeNext Fori=Len(str)To1Step-1 IfAsc(Mid(str,i,1))<> 0AndAsc(Mid(str,i,1))<>32Then fDelInvaildChr=Left(str,i) ExitFor EndIf Next EndFunction
三、遍历主函数 ----参数说明: strPathName要遍历的目录 objList使用VB的内部控 件ListBox来存放遍历得到的路径,之所以 不使用字符串数组是因为数组大小不好定义
PublicSubsDirTraversal (ByValstrPathNameAsString,ByRefobjListAsListBox) DimsSubDir(200)AsString '存放当前目录下的子目录,下标可根据需要调整 DimiIndexAsInteger '子目录数组下标 DimiAsInteger '用于循环子目录的查找
DimlHandleAsLong 'FindFirstFileA的句柄 DimtFindDataAsWIN32_FIND_DATA' DimstrFileNameAsString'文件名
OnErrorResumeNext '初始化变量 i=1 iIndex=0 tFindData.cFileName= ""'初始化定长字符串
lHandle=FindFirstFile (strPathName&"\*.*",tFindData) IflHandle=0Then'查询结束或发生错误 ExitSub EndIf strFileName=fDelInvaildChr(tFindData.cFileName) IftFindData.dwFileAttributes=&H10Then'目录 IfstrFileName<>"."AndstrFileName<>".."Then iIndex=iIndex 1 sSubDir(iIndex)=strPathName &"\"&strFileName'添加到目录数组 EndIf Else objList.AddItemstrPathName &"\"&strFileName EndIf '循环查找下一个文件,直到结束 DoWhileTrue tFindData.cFileName="" IfFindNextFile(lHandle,tFindData) =0Then'查询结束或发生错误 FindClose(lHandle) ExitDo Else strFileName=fDelInvaildChr (tFindData.cFileName) IftFindData.dwFileAttributes=&H10Then IfstrFileName<>"."AndstrFileName<>".."Then iIndex=iIndex 1 sSubDir(iIndex)=strPathName &"\"&strFileName'添加到目录数组 EndIf Else objList.AddItemstrPathName&"\"&strFileName EndIf EndIf Loop '如果该目录下有目录,则根据目录数组递归遍历 IfiIndex>0Then Fori=1ToiIndex sDirTraversalsSubDir(i),objList Next EndIf EndSub
----利用以上遍历方法,读者可以根据数据类型WIN32_FIND_DATA的dwFileAttributes、ftCreationTime、ftLastAccessTime、ftLastWriteTime元素来扩充文件查询功能(按文件属性、创建日期、最后修改日期、最后访问日期等不同条件的查询)。
完整代码:
''''''''''''''''''''''''''''''''''''''''''' 'API函数的声明、常量、自定义数据类型 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'API函数的声明 PublicDeclareFunctionFindFirstFileLib"kernel32"Alias"FindFirstFileA"(ByVallpFileNameAsString,lpFindFileDataAsWIN32_FIND_DATA)AsLong PublicDeclareFunctionFindNextFileLib"kernel32"Alias"FindNextFileA"(ByValhFindFileAsLong,lpFindFileDataAsWIN32_FIND_DATA)AsLong PublicDeclareFunctionFindCloseLib"kernel32"(ByValhFindFileAsLong)AsLong ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'最大路径长度和文件属性常量的定义 PublicConstMAX_PATH=260 PublicConstFILE_ATTRIBUTE_ARCHIVE=&H20 PublicConstFILE_ATTRIBUTE_COMPRESSED=&H800 PublicConstFILE_ATTRIBUTE_DIRECTORY=&H10 PublicConstFILE_ATTRIBUTE_HIDDEN=&H2 PublicConstFILE_ATTRIBUTE_NORMAL=&H80 PublicConstFILE_ATTRIBUTE_READONLY=&H1 PublicConstFILE_ATTRIBUTE_SYSTEM=&H4 PublicConstFILE_ATTRIBUTE_TEMPORARY=&H100
'自定义数据类型FILETIME和WIN32_FIND_DATA的定义 PublicTypeFILETIME dwLowDateTimeAsLong dwHighDateTimeAsLong EndType
PublicTypeWIN32_FIND_DATA dwFileAttributesAsLong ftCreationTimeAsFILETIME ftLastAccessTimeAsFILETIME ftLastWriteTimeAsFILETIME nFileSizeHighAsLong nFileSizeLowAsLong dwReserved0AsLong dwReserved1AsLong cFileNameAsString*MAX_PATH cAlternateAsString*14 EndType
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '去掉固定长度字符串右边的NULL字符(ASCII值为0)和SPACE字符(ASCII值为32)函数 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PublicFunctionfDelInvaildChr(strAsString)AsString OnErrorResumeNext Fori=Len(str)To1Step-1 IfAsc(Mid(str,i,1))<>0AndAsc(Mid(str,i,1))<>32Then fDelInvaildChr=Left(str,i) ExitFor EndIf Next EndFunction
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '遍历主函数 '参数说明: 'strPathName要遍历的目录 'objList使用VB的内部控件ListBox来存放遍历得到的路径,之所以 '不使用字符串数组是因为数组大小不好定义 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' PublicSubsDirTraversal(ByValstrPathNameAsString,ByRefobjListAsListBox) DimsSubDir(200)AsString'存放当前目录下的子目录,下标可根据需要调整 DimiIndexAsInteger'子目录数组下标 DimiAsInteger'用于循环子目录的查找
DimlHandleAsLong'FindFirstFileA的句柄 DimtFindDataAsWIN32_FIND_DATA' DimstrFileNameAsString'文件名
OnErrorResumeNext '初始化变量 i=1 iIndex=0 tFindData.cFileName=""'初始化定长字符串
lHandle=FindFirstFile(strPathName&"\*.*",tFindData) IflHandle=0Then'查询结束或发生错误 ExitSub EndIf strFileName=fDelInvaildChr(tFindData.cFileName) IftFindData.dwFileAttributes=&H10Then'目录 IfstrFileName<>"."AndstrFileName<>".."Then iIndex=iIndex 1 sSubDir(iIndex)=strPathName&"\"&strFileName'添加到目录数组 EndIf Else objList.AddItemstrPathName&"\"&strFileName EndIf '循环查找下一个文件,直到结束 DoWhileTrue tFindData.cFileName="" IfFindNextFile(lHandle,tFindData)=0Then'查询结束或发生错误 FindClose(lHandle) ExitDo Else strFileName=fDelInvaildChr(tFindData.cFileName) IftFindData.dwFileAttributes=&H10Then IfstrFileName<>"."AndstrFileName<>".."Then iIndex=iIndex 1 sSubDir(iIndex)=strPathName&"\"&strFileName'添加到目录数组 EndIf Else objList.AddItemstrPathName&"\"&strFileName EndIf EndIf Loop '如果该目录下有目录,则根据目录数组递归遍历 IfiIndex>0Then Fori=1ToiIndex sDirTraversalsSubDir(i),objList Next EndIf EndSub->
|