2012-10-04 22 views
6

TDirectory.GetFiles hat einen Parameter namens SearchPattern. Die Dokumentation von Embarcadero lautet:Wie werden mehrere Dateierweiterungen an TDirectory.GetFiles übergeben?

Die Maske, die verwendet wird, wenn Dateinamen übereinstimmen (z. B. "* .exe" stimmt mit allen ausführbaren Dateien überein).

Allerdings möchte ich mehrere Dateitypen übergeben. Ich bekomme diese Typen von . Also, es ist eine Zeichenfolge, die wie '*.txt;*.rtf;*.doc' aussieht.

Ich habe versucht, diese Zeichenfolge direkt an GetFiles übergeben und es funktioniert nicht. Muss ich es analysieren, zerlegen und jedes einzelne Stück an GetFiles füttern?

Antwort

11

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.

+0

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. –

+0

Ja, offensichtlich können Sie Ihre sep char von einem der illegalen Dateinamen Chars –

+0

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

Verwandte Themen