|
Registriert seit: 1. Feb 2018 3.691 Beiträge Delphi 11 Alexandria |
#15
Falls sich die Anforderungen mal steigern und Du mehr Geschwindigkeit bei der Dateisuche brauchst, das hier habe ich mir mal gebastelt:
Ich kann unter keinen Umständen empfehlen die 2 sub-routinen zu ändern aber der wrapper "FindEx" kann natürlich beliebig umgeschrieben und angepasst werden. Ein paar Erklärungen sind in Englisch enthalten.
Delphi-Quellcode:
unit uFindEx;
interface uses Winapi.Windows, System.SysUtils; type // My variant of an "StringList" TFindArray = TArray<string>; // array of WideString; function FindEx(const ABasePath: string; const AFoldersMustExist: string = ''; AExludedFolders: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; implementation const // missing FindEx flags FIND_FIRST_EX_CASE_SENSITIVE = $00000001; FIND_FIRST_EX_LARGE_FETCH = $00000002; FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY = $00000004; // Small helper to add strings in my "StringList" procedure AddFindArray(var AFindArray: TFindArray; const AString: string); inline; var i: Integer; begin i := Length(AFindArray); SetLength(AFindArray, Succ(i)); AFindArray[i] := AString; end; // This method will crawl thru a folder and collect their names // The ExclusionList should contain full path names that be total excluded from search, by default everything is included // IncludeSubFolders switch will get every folder, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path function FindExFolders(const ABasePath: string = ''; const AExclusionList: TFindArray = []; const AIncludeSubFolders: Boolean = False): TFindArray; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFindexInfoLevels; FindExSearchOps : TFindexSearchOps; AdditionalFlags : DWORD; tmp : TFindArray; i, ii : Integer; s:string; begin SetLength(Result, 0); if ((ABasePath = '') or (not DirectoryExists(ABasePath))) then Exit; FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Winapi.Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(ABasePath) + '*.*') ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then begin repeat if ((Win32FindData.cFileName <> string('.')) and (Win32FindData.cFileName <> string('..')) and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then begin if (Length(AExclusionList) > 0) then begin for i := Low(AExclusionList) to High(AExclusionList) do if (0 = Pos(UpperCase(AExclusionList[i]), UpperCase(IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName))) then AddFindArray(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end else AddFindArray(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end; until (not Winapi.Windows.FindNextFileW(FindExHandle, Win32FindData)); Winapi.Windows.FindClose(FindExHandle); end; if AIncludeSubFolders then for i := Low(Result) to High(Result) do begin tmp := FindExFolders(Result[i], AExclusionList, AIncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddFindArray(Result, tmp[ii]); end; SetLength(tmp, 0); end; // This method will crawl thru a folder and collect their filenames // IncludeSubFolders switch will get every filename, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path + filename function FindExFiles(const ABasePath: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFindexInfoLevels; FindExSearchOps : TFindexSearchOps; AdditionalFlags : DWORD; tmp, Folders : TFindArray; i, ii : Integer; begin SetLength(Result, 0); if ((ABasePath = '') or (not DirectoryExists(ABasePath))) then Exit; SetLength(Folders, 0); SetLength(tmp, 0); FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Winapi.Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(ABasePath) + AFileMask) ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then begin repeat if ((Win32FindData.cFileName <> string('.')) and (Win32FindData.cFileName <> string('..'))) then begin if (0 = (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)) then AddFindArray(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); if (AIncludeSubFolders and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then AddFindArray(Folders, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end; until (not Winapi.Windows.FindNextFileW(FindExHandle, Win32FindData)); Winapi.Windows.FindClose(FindExHandle); end; if AIncludeSubFolders then for i := Low(Folders) to High(Folders) do begin tmp := FindExFiles(Folders[i], AFileMask, AIncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddFindArray(Result, tmp[ii]); end; SetLength(Folders, 0); SetLength(tmp, 0); end; // My variant of how a file search method can be done for windows systems // BasePath = where do we start at? eg "C:\Users" // FoldersMustExist = what foldername is a must for results? eg "Documents", can be left empty for all (seperate with ";" if more than 1) // ExludedFolders = in what foldername you do not want to search? eg "Documents", can be left empty for all (seperate with ";" if more than 1) // FileMask = what files you hunt for? eg "*.pas" // IncludeSubFolders = yes or no, you choose. False by default // based upon my "FindExFolders" and "FindExFiles" methods function FindEx(const ABasePath: string; const AFoldersMustExist: string = ''; AExludedFolders: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; var tmp, Folders, Files: TFindArray; splitIncluded, splitExcluded: TFindArray; i, ii: Integer; begin SetLength(Result, 0); SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); SetLength(splitIncluded, 0); SetLength(splitExcluded, 0); // prepare splittings if (Length(AFoldersMustExist) > 0) then begin if (0 <> Pos(';', AFoldersMustExist)) then splitIncluded := AFoldersMustExist.Split([';']) else AddFindArray(splitIncluded, AFoldersMustExist); end; if (Length(AExludedFolders) > 0) then begin if (0 <> Pos(';', AExludedFolders)) then splitExcluded := AExludedFolders.Split([';']) else AddFindArray(splitExcluded, AExludedFolders); end; // collect folder(s) to work on if AIncludeSubFolders then tmp := FindExFolders(ABasePath, splitExcluded, AIncludeSubFolders) else AddFindArray(tmp, ABasePath); // sieve out folders that match criteria if (Length(splitIncluded) > 0) then begin for i := Low(tmp) to High(tmp) do for ii := Low(splitIncluded) to High(splitIncluded) do if (0 <> Pos(UpperCase(splitIncluded[ii]), UpperCase(tmp[i]))) then AddFindArray(Folders, tmp[i]); end else Folders := tmp; // get files that matching the criteria for i := Low(Folders) to High(Folders) do begin if (Length(AFileMask) > 0) then tmp := FindExFiles(Folders[i], AFileMask) // do not enable the IncludeSubFolders switch here (!) else tmp := FindExFiles(Folders[i]); for ii := Low(tmp) to High(tmp) do AddFindArray(Files, tmp[ii]); end; Result := Files; SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); SetLength(splitIncluded, 0); SetLength(splitExcluded, 0); end; end.
Gruß vom
![]() |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |