Difference between revisions of "Searching directories recursively"
From HashVB
(Tidied up the sample code and corrected the function name) |
|||
Line 47: | Line 47: | ||
The code that will actually recurse through the directories goes like this: | The code that will actually recurse through the directories goes like this: | ||
− | Public Function | + | Public Function CountDirSize(ByVal StartDir As String) As Double |
− | Dim | + | Dim Filename As String |
Dim hSearch As Long | Dim hSearch As Long | ||
Dim WFD As WIN32_FIND_DATA | Dim WFD As WIN32_FIND_DATA | ||
Line 54: | Line 54: | ||
Dim DirSize As Double | Dim DirSize As Double | ||
+ | 'Add the final \ | ||
If Right$(StartDir, 1) <> "\" Then StartDir = StartDir & "\" | If Right$(StartDir, 1) <> "\" Then StartDir = StartDir & "\" | ||
− | + | ||
+ | 'Enumerate the directories | ||
hSearch = FindFirstFile(StartDir & "*", WFD) | hSearch = FindFirstFile(StartDir & "*", WFD) | ||
If hSearch <> INVALID_HANDLE_VALUE Then | If hSearch <> INVALID_HANDLE_VALUE Then | ||
Cont = True | Cont = True | ||
Do While Cont | Do While Cont | ||
− | + | Filename = StripNulls(WFD.cFileName) | |
'Ignore the current and encompassing directories. | 'Ignore the current and encompassing directories. | ||
− | If ( | + | If (Filename <> ".") And (Filename <> "..") Then |
'Check if it's a directory | 'Check if it's a directory | ||
− | If GetFileAttributes(StartDir & | + | If GetFileAttributes(StartDir & Filename) And FILE_ATTRIBUTE_DIRECTORY Then |
− | Debug.Print "DIR", StartDir & | + | Debug.Print "DIR", StartDir & Filename |
− | DirSize = DirSize + | + | DirSize = DirSize + CountDirSize(StartDir & Filename) |
Else | Else | ||
− | Debug.Print "FILE", StartDir & | + | Debug.Print "FILE", StartDir & Filename |
DirSize = DirSize + CDbl(CStr(WFD.nFileSizeHigh)) * (MAXDWORD + 1) + WFD.nFileSizeLow | DirSize = DirSize + CDbl(CStr(WFD.nFileSizeHigh)) * (MAXDWORD + 1) + WFD.nFileSizeLow | ||
End If | End If | ||
Line 78: | Line 80: | ||
End If | End If | ||
− | + | CountDirSize = DirSize | |
End Function | End Function | ||
Latest revision as of 13:53, 5 January 2007
This article is based on Visual Basic 6. Find other Visual Basic 6 articles. |
This is a useful technique that allows you to search for files and build directory trees a lot faster than the intrinsic VB methods allow.
It involves the use of the file finding APIs, the declarations for which are as follows:
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 GetFileAttributes Lib "kernel32" Alias "GetFileAttributesA" _ (ByVal lpFileName As String) As Long Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long Const MAX_PATH = 260 Const INVALID_HANDLE_VALUE = -1 Const FILE_ATTRIBUTE_ARCHIVE = &H20 Const FILE_ATTRIBUTE_DIRECTORY = &H10 Const FILE_ATTRIBUTE_HIDDEN = &H2 Const FILE_ATTRIBUTE_NORMAL = &H80 Const FILE_ATTRIBUTE_READONLY = &H1 Const FILE_ATTRIBUTE_SYSTEM = &H4 Const FILE_ATTRIBUTE_TEMPORARY = &H100 Const MAXDWORD As Long = &HFFFFFFFF Private Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type 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: I have also included all the other necessary declarations for using the code below.
The code that will actually recurse through the directories goes like this:
Public Function CountDirSize(ByVal StartDir As String) As Double Dim Filename As String Dim hSearch As Long Dim WFD As WIN32_FIND_DATA Dim Cont As Integer Dim DirSize As Double 'Add the final \ If Right$(StartDir, 1) <> "\" Then StartDir = StartDir & "\" 'Enumerate the directories hSearch = FindFirstFile(StartDir & "*", WFD) If hSearch <> INVALID_HANDLE_VALUE Then Cont = True Do While Cont Filename = StripNulls(WFD.cFileName) 'Ignore the current and encompassing directories. If (Filename <> ".") And (Filename <> "..") Then 'Check if it's a directory If GetFileAttributes(StartDir & Filename) And FILE_ATTRIBUTE_DIRECTORY Then Debug.Print "DIR", StartDir & Filename DirSize = DirSize + CountDirSize(StartDir & Filename) Else Debug.Print "FILE", StartDir & Filename DirSize = DirSize + CDbl(CStr(WFD.nFileSizeHigh)) * (MAXDWORD + 1) + WFD.nFileSizeLow End If End If Cont = FindNextFile(hSearch, WFD) Loop Cont = FindClose(hSearch) End If CountDirSize = DirSize End Function Function StripNulls(OriginalStr As String) As String If (InStr(OriginalStr, Chr(0)) > 0) Then OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1) End If StripNulls = OriginalStr End Function
This will print all of the files, directories and subdirectories under the directory that you provide it with to the Immediate window, and, as an added bonus, returns the total size of the files in the directory tree.
Enjoy.