【问题标题】:How to pass multiple file extensions to TDirectory.GetFiles?如何将多个文件扩展名传递给 TDirectory.GetFiles?
【发布时间】:2012-09-25 11:01:03
【问题描述】:

TDirectory.GetFiles 有一个名为SearchPattern 的参数。 Embarcadero 的文档说

匹配文件名时使用的掩码(例如,“*.exe”匹配所有可执行文件)。

但是,我想传递多种文件类型。我从FilterComboBox.Mask 获得这些类型。所以,它是一个看起来像'*.txt;*.rtf;*.doc' 的字符串。

我试图将该字符串直接传递给GetFiles,但它不起作用。我是否必须对其进行解析,将其分成几块并将每一块都提供给GetFiles

【问题讨论】:

    标签: delphi delphi-xe


    【解决方案1】:

    GetFiles 背后的 RTL 代码调用 Masks.MatchesMask 来测试是否与您的搜索模式匹配。此函数仅支持对单个掩码进行掩码。

    替代方法是使用允许TFilterPredicateGetFiles 重载。您提供一个谓词来测试名称是否与您的模式匹配。

    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 的堆。我可以想象这是长时间搜索的性能瓶颈。在这种情况下,您可以从MaskArray 创建一个TMask 对象数组。并使用谓词中的那些来测试。我不知道这是否是一个有效的问题,只是我在阅读代码时发生的事情。

    【讨论】:

    • 不错的一个。 +1当使用名称中带有分号的文件时,它有点中断,但这不是这个例程的错。我一直不明白他们为什么不使用管道之类的东西来分隔面具。
    • 是的,显然您可以从非法文件名字符之一中选择您的 sep 字符
    • 谢谢。我知道谓词。我只是想确保确实没有直接支持多种文件类型的函数。
    • > 我不知道这是否是一个有效的问题 - - - 我想这是因为有数百万个文件。很好的收获。
    猜你喜欢
    • 2016-12-13
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多