Как передать несколько расширений файлов в TDirectory.GetFiles?

TDirectory.GetFiles имеет параметр, называемый SearchPattern. Документация Embarcadero говорит

маска, используемая при сопоставлении имен файлов (например,"*.exe " соответствует всем исполняемым файлам).

однако я хочу передать несколько типов файлов. Я получаю эти типы от FilterComboBox.Mask. Итак, это строка, которая выглядит так:'*.txt;*.rtf;*.doc'.

Я попытался передать эту строку непосредственно к GetFiles и это не работает. Я должен разобрать его, разбейте его на куски и накормите каждую отдельную часть GetFiles?

1 ответов


код RTL позади GetFiles звонки Masks.MatchesMask чтобы проверить соответствие вашему шаблону поиска. Эта функция поддерживает маскировку только против одной маски.

альтернативой является использование GetFiles перегрузка, которая допускает TFilterPredicate. Вы предоставляете предикат, который проверяет, соответствует ли имя вашему шаблону.

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;

отметим, что MatchesMask создает и уничтожает выделенную кучу TMask каждый раз, когда он вызывается. Я могу ... представьте, что это узкое место производительности в течение длительного поиска. В этом случае вы можете создать массив TMask объекты MaskArray. И используйте их в предикате для проверки. Я понятия не имею, является ли это действительной проблемой или нет, просто что-то, что пришло мне в голову во время просмотра кода.