VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 查找第一个文件
发表评论(0)作者:不详, 平台:VB6.0+Win98, 阅读:8537, 日期:2001-05-10
FindFirstFile                                     by Tracy Martin
Available under: Windows 95, Windows 98, Windows NT
Exported from: Kernel32.DLL

The FindFirstFile / FindNextFile / FindClose APIs are used for searching for various files. I have written a sample class which encapsulates these API calls, with various portions of the class code copied below.  

When using these APIs it is important to remember that failing to close a Find can result in files or directories not being available for some operations (such as deletes). This is because these APIs open a handle to the objects being searched, and the operating system won注释:t allow you to do certain things to an object as long as an active handle to that object exists.  

Also, the data structure used by these APIs contains string data, which is terminated by null characters. These need to be removed prior to using the actual data. (I found it easiest to write a simple routine to "clean up" the data in the structure after each call.)
Declarations for the functions:

Private Declare Function APIFindFirstFile _
Lib "kernel32" _
Alias "FindFirstFileA" _
(ByVal lpFileName As String, _
lpFindFileData As WIN32_FIND_DATA) As Long

Private Declare Function APIFindNextFile _
Lib "kernel32" _
Alias "FindNextFileA" _
(ByVal hFindFile As Long, _
lpFindFileData As WIN32_FIND_DATA) As Long

Private Declare Function APIFindClose _
Lib "kernel32" _
Alias "FindClose" _
(ByVal hFindFile As Long) As Long

Declaration for the structure used by these functions:

Private 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

Note that other APIs are also useful when using these calls:

FileTimeToSystemTime
FileTimeToLocalFileTime
GetFullPathName
GetShortPathName

These are covered in more detail on other pages.
Here are the basics of how to call these APIs. For more details, download the sample class.  

Public Function FindFile(ByVal pstrName As String) As Boolean

注释: FindFile: search for a file or directory
注释:
注释: Incoming parameters:
注释: pstrName (String): File to search for. This may contain 注释: any, all, or none of the following:
注释: a fully qualified path
注释: a specific file name
注释: wildcards (within file name only)
注释: If this item is null, "*.*" will be substituted.
注释: If no path is specified, the current directory will be 注释: searched.
注释:
注释: Returned parameters:
注释: Boolean: True if search is successful, false otherwise
注释:
注释: Global Variables Modified:
注释: hFind: Holds handle to opened Find for later use
注释: FileData: Receives file data returned from API
注释: sFullPath: Holds full path to located file, minus file name, for future use
注释: sShortPath: Holds short (8.3) path to located file, minus file name, for future use
注释:
注释: Local Variables:
注释: nPathLen (Long): Length of path name (used for creating buffer)
注释: pName (Long): Unused variable (pointer to short name - actual pointer, not offset)
注释: iPos (Integer): Offset of "\" when separating path and file name
注释: sName (String): Used to separate file name from path name
注释: bCont (Boolean): Used to detect when to end loop separating 注释: path and file name

Dim nPathLen As Long, pName As Long
Dim sName As String
Dim bCont As Boolean, iPos As Integer

注释: If hFind is not null, then a previous search was not closed, so close it now.
If hFind <> 0 Then
FindClose
End If

注释: If pstrName is null, replace it with "*.*"
If pstrName = "" Then pstrName = "*.*"

注释: If a path with no file was specified, append "*.*"
If Right(pstrName, 1) = "\" Then
pstrName = pstrName + "*.*"
End If

hFind = APIFindFirstFile(pstrName, FileData)

注释: If hFind is -1 (INVALID_HANDLE_VALUE), the search failed
If hFind = INVALID_HANDLE_VALUE Then
hFind = 0
FindFile = False
Exit Function
End If

注释: Clean up remnants left by the API, such as null characters, and convert returned time structures from UTC to local
CleanFileData

注释: Get the full path for the search, so that we can use it later
nPathLen = GetFullPathName(pstrName, 0, sFullPath, pName)
sFullPath = String(nPathLen, " ")
nPathLen = GetFullPathName(pstrName, nPathLen, sFullPath, pName)

注释: Clean these up (remove nulls, etc.)
sFullPath = Left(sFullPath, InStr(sFullPath, Chr(0)) - 1)
sName = sFullPath

注释: Cut the filename off the path, so that we have a "generic" path for the search set
sFullPath = ""
bCont = True
While bCont
iPos = InStr(sName, "\")
If iPos = 0 Then
bCont = False
Else
sFullPath = sFullPath & Left(sName, iPos)
sName = Right(sName, Len(sName) - iPos)
End If
Wend

注释: Get the "short" path (8.3 names) for the search, so we can use it later
nPathLen = GetShortPathName(sFullPath, sShortPath, 0)
sShortPath = String(nPathLen, " ")
nPathLen = GetShortPathName(sFullPath, sShortPath, 0)

注释: Clean it up (remove nulls, etc.)
sShortPath = Left(sShortPath, InStr(sShortPath, Chr(0)))
If sShortPath = "" Then sShortPath = sFullPath
If Right(sShortPath, 1) <> "\" Then sShortPath = sShortPath + "\"

注释: If we made it here, we were successful, so get out
FindFile = True

End Function

Public Function FindNextFile() As Boolean
注释: FindNextFile: continue the search started with FindFile
注释:
注释: Incoming parameters:
注释: <none>
注释:
注释: Returned parameters:
注释: Boolean: True if search is successful, false otherwise
注释:
注释: Global Variables Modified:
注释: FileData: Receives file data returned from API
注释:
注释: Local Variables:
注释: bResult (Boolean): Holds result code from API call

Dim bResult As Boolean

注释: If hFind is null, the search was closed - must call FindFile before FindNextFile
If hFind = 0 Then
FindNextFile = False
Exit Function
End If

bResult = APIFindNextFile(hFind, FileData)

注释: If the search was successful, clean up the returned data
If bResult Then
CleanFileData
End If

FindNextFile = bResult

End Function

Public Sub FindClose()
注释: FindClose: Close the current search
注释:
注释: Incoming parameters:
注释: <none>
注释:
注释: Returned parameters:
注释: <none>
注释:
注释: Global Variables Modified:
注释: hFind: Cleared to indicate that find is closed
注释: sFullPath: Cleared in preparation for next find
注释: sShortPath: Cleared in preparation for next find

注释: Dump our previously saved paths, as they are no longer needed.
sFullPath = ""
sShortPath = ""

注释: if hFind is Null, the search is already closed - no need to do it again.
If hFind <> 0 Then
APIFindClose hFind
hFind = 0
End If

End Sub