Datei-Suche mit API
Dateien mithilfe des Win32-API suchen
Man kann es sich fast denken – die Win32-API Funktion ist die umfangreichste Variante. Bevor überhaupt eine Routine erstellt werden kann, sind einige modulglobale Deklarationen notwendig. Darüber hinaus benötigen diese Funktion 2 bestimmte Strukturen und Konstanten. Der nachfolgende Teil ist modulglobal zu hinterlegen; d.h. außerhalb einer Routine im Kopfbereich eines Moduls:
Beispiel:
Option Explicit Const MAX_PATH = 260 Const INVALID_HANDLE_VALUE = -1 Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type 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 Declare Function GetWindowsDirectory Lib "kernel32" Alias _ "GetWindowsDirectoryA" _ (ByVal lpBuffer As String, _ ByVal nSize As Long) As Long Declare Function FindFirstFile Lib "kernel32" Alias _ "FindFirstFileA" _ (ByVal lpFileName As String, _ lpFindFileData As WIN32_FIND_DATA) As Long Declare Function FindNextFile Lib "kernel32" Alias _ "FindNextFileA" _ (ByVal hFindFile As Long, _ lpFindFileData As WIN32_FIND_DATA) As Long Declare Function FindClose Lib "kernel32" _ (ByVal hFindFile As Long) As Long
Nach diesen Vorbereitungen sind wir in der Lage, die API-Lösung zu erstellen:
Beispiel:
' Die API-Variante Sub API_GetIniFiles() Dim uWFD As WIN32_FIND_DATA 'Strukturvariable für API-Suche Dim sBuffer As String 'Hilfsvariable Dim sWinDir As String 'Windows-Ordner Dim lCounter As Long 'Zählervariable Dim lResult As Long 'API-Rückgabewert Dim lFile As Long 'Datei-Handle Dim asFiles() As String 'Datenfeld für die Ergebnisdateien 'Zunächst das Windows-Verzeichnis ermitteln sBuffer = Space(260) lResult = GetWindowsDirectory(sBuffer, Len(sBuffer)) If lResult <> 0 Then sWinDir = Left$(sBuffer, lResult) 'Falls nicht vorhanden, einen Backslash anfügen If Right$(sWinDir, 1) <> "\" Then sWinDir = sWinDir & "\" Else: Exit Sub End If 'Erste Suche starten lFile = FindFirstFile(sWinDir & "*.ini", uWFD) 'Wenn es ein gültiges Dateihandle gibt If lFile <> INVALID_HANDLE_VALUE Then lCounter = 0 Do 'Zählervariable für das Array vergrößern lCounter = lCounter + 1 'Array um 1 Eintrag erweitern (Re-Dimensionieren) ReDim Preserve asFiles(lCounter) 'In dem neuen Array-Eintrag den ersten Dateinamen speichern asFiles(lCounter - 1) = uWFD.cFileName 'Feld in der Struktur initialisieren uWFD.cFileName = vbNullString 'Solange weitersuchen, bis kein Treffer mehr vorliegt Loop While FindNextFile(lFile, uWFD) 'Dateihandle explizit schließen! lFile = FindClose(lFile) End If 'Ergebnistest - alle Array-Einträge im Direktfenster ausgeben For lCounter = LBound(asFiles) To UBound(asFiles) If Len(asFiles(lCounter)) > 0 Then Debug.Print "Eintrag"; lCounter; ": "; asFiles(lCounter) End If Next End Sub
Mit dieser 3. Variante schließen wir die Dateisuche ab – welche Variante zu bevorzugen ist, ist letztendlich Geschmacksache. Je nach Art und Menge der zu suchenden Dateien gibt es durchaus zeitliche Unterschiede, wobei wohl die API-Variante die Schnellste (aber auch Aufwändigste) ist.