德尔福的文件掩码

Gle*_*rse 4 delphi mask

我试图找到所有具有扩展名.cbr或.cbz的文件

如果我将我的面具设置为*.cb?

它找到*.cbproj文件.如何将掩码设置为仅查找.cbr和.cbz文件?

这是我正在使用的代码.

我有两个编辑框EDIT1是搜索的位置,EDIT2是我把我的面具放在哪里.用于显示找到内容的列表框和"搜索"按钮.

edit1 := c:\
edit2 := mask (*.cb?)
Run Code Online (Sandbox Code Playgroud)

空间

    procedure TFAutoSearch.FileSearch(const PathName, FileName : string; const InDir : boolean);
var Rec  : TSearchRec;
    Path : string;
begin
Path := IncludeTrailingBackslash(PathName);
if FindFirst(Path + FileName, faAnyFile - faDirectory, Rec) = 0 then
 try
   repeat
     ListBox1.Items.Add(Path + Rec.Name);
   until FindNext(Rec) <> 0;
 finally
   FindClose(Rec);
 end;

If not InDir then Exit;

if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then
 try
   repeat
    if ((Rec.Attr and faDirectory) <> 0)  and (Rec.Name<>'.') and (Rec.Name<>'..') then
     FileSearch(Path + Rec.Name, FileName, True);
   until FindNext(Rec) <> 0;
 finally
   FindClose(Rec);
 end;
end; //procedure FileSearch



procedure TFAutoSearch.Button1Click(Sender: TObject);
begin
  FileSearch(Edit1.Text, Edit2.Text, CheckBox1.State in [cbChecked]);
end;

end.
Run Code Online (Sandbox Code Playgroud)

LaK*_*ven 7

最简单的方法是使用ExtractFileExt当前文件名并检查它是否与您想要的扩展名匹配.

这是你的FileSearch例程的完全重写版本,它正是你正在尝试做的事情(无论如何根据你的问题):

procedure TFAutoSearch.FileSearch(const ARoot: String);
var
  LExt, LRoot: String;
  LRec: TSearchRec;
begin
  LRoot := IncludeTrailingPathDelimiter(ARoot);
  if FindFirst(LRoot + '*.*', faAnyFile, LRec) = 0 then
  begin
    try
      repeat
        if (LRec.Attr and faDirectory <> 0) and (LRec.Name <> '.') and (LRec.Name <> '..') then
          FileSearch(LRoot + LRec.Name)
        else
        begin
          LExt := UpperCase(ExtractFileExt(LRoot + LRec.Name));
          if (LExt = '.CBR') or (LExt = '.CBZ') then
            ListBox1.Items.Add(LRoot + LRec.Name);
        end;
      until (FindNext(LRec) <> 0);
    finally
      FindClose(LRec);
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

虽然另一个答案暗示使用多个扩展作为掩码*.cbr;*.cbz应该(原则上无论如何)工作,但我已经通过痛苦的经验注意到Delphi 中的FindFirstFindNext方法往往不接受掩码中的多个扩展!

我提供的代码应该可以满足您的需求,所以尽情享受吧!

更新:允许在运行时动态地在Mask中使用多个扩展(如OP对此答案的第一个注释所示).

我们要做的是String从你的TEdit控件中取出一个(这String是你想要的一个或多个文件扩展名),"爆炸" String成一个Array,并将每个文件与每个扩展名相匹配Array.

听起来比这更复杂:

type
  TStringArray = Array of String; // String Dynamic Array type...

// Now let's provide a "Mask Container" inside the containing class...
  TFAutoSearch = class(TForm)
    // Normal stuff in here
  private
    FMask: TStringArray; // Our "Mask Container"
  end;
Run Code Online (Sandbox Code Playgroud)

此代码将填充FMask每个单独的掩码扩展名,;例如.CBR;.CBZ.

请注意,此方法不接受通配符或任何其他正则表达式魔法,但您可以根据需要进行修改!

procedure TFAutoSearch.ExplodeMask(const AValue: String);
var
  LTempVal: String;
  I, LPos: Integer;
begin
  LTempVal := AValue;
  I := 0;
  while Length(LTempVal) > 0 do
  begin
    Inc(I);
    SetLength(FMask, I);
    LPos := Pos(';', LTempVal);

    if (LPos > 0) then
    begin
      FMask[I - 1] := UpperCase(Copy(LTempVal, 0, LPos - 1));
      LTempVal := Copy(LTempVal, LPos +  1, Length(LTempVal));
    end
    else
    begin
      FMask[I - 1] := UpperCase(LTempVal);
      LTempVal := EmptyStr;
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我们现在需要一个函数来确定指定的文件是否与任何已定义的Extensions匹配:

function TFAutoSearch.MatchMask(const AFileName: String): Boolean;
var
  I: Integer;
  LExt: String;
begin
  Result := False;
  LExt := UpperCase(ExtractFileExt(LExt));
  for I := Low(FMask) to High(FMask) do
    if (LExt = FMask[I]) then
    begin
      Result := True;
      Break;
    end;
end;
Run Code Online (Sandbox Code Playgroud)

现在这是修改FileSearch过程:

procedure TFAutoSearch.FileSearch(const ARoot: String);
var
  LRoot: String;
  LRec: TSearchRec;
begin
  LRoot := IncludeTrailingPathDelimiter(ARoot);
  if FindFirst(LRoot + '*.*', faAnyFile, LRec) = 0 then
  begin
    try
      repeat
        if (LRec.Attr and faDirectory <> 0) and (LRec.Name <> '.') and (LRec.Name <> '..') then
          FileSearch(LRoot + LRec.Name)
        else
        begin
          if (MatchMask(LRoot + LRec.Name)) then
            ListBox1.Items.Add(LRoot + LRec.Name);
        end;
      until (FindNext(LRec) <> 0);
    finally
      FindClose(LRec);
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

最后,以下是您启动搜索的方式:

procedure TFAutoSearch.btnSearchClick(Sender: TObject);
begin
  ExplodeMask(edMask.Text);
  FileSearch(edPath.Text);
end;
Run Code Online (Sandbox Code Playgroud)

edMask在你的问题定义Edit2,并edPath在你的问题的定义Edit1.请记住,此方法不支持使用通配符或其他特殊字符,所以edMask.Text应该是这样的.CBR;.CBZ

如果您使用Delphi的Regex库,您可以轻松修改此方法以支持您可以想象的所有表达式案例!