Der RTL-Code hinter GetFiles
ruft Masks.MatchesMask
auf, um eine Übereinstimmung mit Ihrem Suchmuster zu testen. Diese Funktion unterstützt nur die Maskierung gegen eine einzelne Maske.
Die Alternative ist die Verwendung der GetFiles
Überlastung, die eine TFilterPredicate
zulässt. Sie liefern ein Prädikat, das testet, ob ein Name mit Ihrem Muster übereinstimmt oder nicht.
uses
StrUtils, Types, Masks, IOUtils;
function MyGetFiles(const Path, Masks: string): TStringDynArray;
var
MaskArray: TStringDynArray;
Predicate: TDirectory.TFilterPredicate;
begin
MaskArray := SplitString(Masks, ';');
Predicate :=
function(const Path: string; const SearchRec: TSearchRec): Boolean
var
Mask: string;
begin
for Mask in MaskArray do
if MatchesMask(SearchRec.Name, Mask) then
exit(True);
exit(False);
end;
Result := TDirectory.GetFiles(Path, Predicate);
end;
Sie beachten Sie, dass MatchesMask
erzeugt und zerstört ein Haufen TMask
jedes Mal, sie genannt wird zugewiesen. Ich kann mir gut vorstellen, dass dies bei einer langen Suche ein Performance-Engpass ist. In diesem Fall könnten Sie ein Array von TMask
Objekten aus MaskArray
erstellen. Und verwende diese im Prädikat, um zu testen. Ich habe keine Ahnung, ob das ein berechtigtes Anliegen ist oder nicht, nur etwas, das mir bei der Durchsicht des Codes aufgefallen ist.
Nice one. +1 Es bricht, wenn Dateien mit einem Semikolon im Namen verwendet werden, aber das ist nicht der Fehler dieser Routine. Ich habe nie verstanden, warum sie nicht so etwas wie eine Pfeife benutzten, um Masken zu trennen. –
Ja, offensichtlich können Sie Ihre sep char von einem der illegalen Dateinamen Chars –
Danke wählen. Ich weiß über Prädikate. Ich wollte nur sicherstellen, dass es tatsächlich keine Funktion gibt, die mehrere Dateitypen direkt unterstützt. – Ampere