Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
Delphi 12 Athens
|
AW: Schnelle Methode, um eine Dateiliste zu erstellen
24. Feb 2021, 14:59
Bei dem Exclude-Fall müsste man unterscheiden, ob lediglich ein Verzeichnis angegeben ist oder ein Verzeichnis mit Wildcards. Im ersten Fall kann man das Verzeichnis überspringen (das macht mein erster Vorschlag), aber im zweiten Fall muss das Verzeichnis gescannt und die entsprechenden Einträge ausgefiltert werden.
Um das besser kontrollieren zu können, würde ich die LstExclude in zwei Listen LstExcludeDirs und LstExcludeFiles aufsplitten. Hier nochmal ein etwas komplexerer Ansatz (mit kleiner Optimierung beim Checken der Excludes) - ungetestet:
Delphi-Quellcode:
procedure ListFiles(const Root: string; LstInclude, LstExclude, Target: TStrings);
function Matches(const Value: String; const Arr: TArray<string>): Boolean;
var
foundIndex: Integer;
begin
Result := TArray.BinarySearch<string>(Arr, Value, foundIndex, TIStringComparer.Ordinal);
if not Result and (foundIndex > 0) then
Result := Value.StartsWith(Arr[foundIndex-1], True);
end;
var
arr: TArray<string>;
lstExcludeDirs: TStringList;
lstExcludeFiles: TStringList;
mask: string;
path: string;
S: string;
begin
if (LstInclude <> nil) and (LstInclude.Count > 0) then begin { Includes vorhanden? }
for S in LstInclude do begin
path := TPath.Combine(Root, S);
mask := '*.*';
if path.Contains('*') or path.Contains('?') then begin
mask := TPath.GetFileName(path);
path := TPath.GetDirectoryName(path);
end;
Target.AddStrings(TDirectory.GetFiles(path, mask, TSearchOption.soAllDirectories));
end;
end
else if (LstExclude <> nil) and (LstExclude.Count > 0) then begin { Excludes vorhanden? }
lstExcludeDirs := TStringList.Create;
try
lstExcludeFiles := TStringList.Create;
try
for S in LstExclude do begin
path := S;
if path.Contains('*') or path.Contains('?') then begin
LstExcludeFiles.Add(path);
{ damit der Pfad erstmal excluded wird, tragen wir ihn auch in die andere Liste ein }
path := TPath.GetDirectoryName(path);
end;
LstExcludeDirs.Add(path);
end;
{ Erst arbeiten wir die ganzen Pfade ab und überspringen die Excluded Pfade }
{ Für bessere Performance sortieren wir die Excludes einmal, damit wir in Matches das BinarySearch verwenden können }
arr := LstExcludeDirs.ToStringArray;
TArray.Sort<string>(arr, TIStringComparer.Ordinal);
for path in TDirectory.GetDirectories(Root, '*', TSearchOption.soAllDirectories) do begin
{ ist es ein Exclude Path? }
if not Matches(path, arr) then
Target.AddStrings(TDirectory.GetFiles(path, '*.*', TSearchOption.soTopDirectoryOnly));
end;
{ nun noch die excluded Paths mit den Wildcard-Einträgen }
for S in lstExcludeFiles do begin
mask := TPath.GetFileName(S);
path := TPath.GetDirectoryName(S);
Target.AddStrings(TDirectory.GetFiles(path, '*.*', TSearchOption.soAllDirectories,
function(const Path: string; const SearchRec: TSearchRec): Boolean
begin
Result := TPath.MatchesPattern(SearchRec.Name, mask, False);
end
));
end;
finally
lstExcludeFiles.Free;
end;
finally
lstExcludeDirs.Free;
end;
end
else begin { keine Einschränkungen }
Target.AddStrings(TDirectory.GetFiles(Root, '*.*', TSearchOption.soAllDirectories));
end;
end;
|
|
Zitat
|