如何使用FindFirst搜索不同的文件类型?

问题描述 投票:0回答:3

在我的应用程序中,我使用以下过程递归扫描任何文件夹和子文件夹,如果该文件夹包含文本文件 (*.txt),我会将文件名添加到我的过程中定义的 TStringList:

procedure FileSearch(const PathName: string; var lstFiles: TStringList);
const
  FileMask = '*.txt';
var
  Rec: TSearchRec;
  Path: string;
begin
  Path := IncludeTrailingBackslash(PathName);
  if FindFirst(Path + FileMask, faAnyFile - faDirectory, Rec) = 0 then
    try
      repeat
        lstFiles.Add(Path + Rec.Name);
      until FindNext(Rec) <> 0;
    finally
      FindClose(Rec);
    end;

  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, lstFiles);
      until FindNext(Rec) <> 0;
    finally
      FindClose(Rec);
    end;
end;

一切都很完美,但我希望能够搜索多个文件扩展名。我尝试修改 FileMask 来执行此操作,但每次它都没有返回任何内容,可能是因为它正在寻找无效的扩展名。我已经尝试了以下每一项,但没有运气:(显然一次尝试一个,我没有在我的程序中将以下行写 3 次)

FileMask = '*.txt|*.rtf|*.doc';

FileMask = '*.txt;*.rtf;*.doc';

FileMask = '*.txt,*.rtf,*.doc';

我觉得问这个很傻,但是如何允许额外的文件扩展名包含在搜索中?我可以对“打开”和“保存”对话框执行此操作,为什么我不能在此处分离扩展名?

谢谢。

克雷格。

delphi wildcard
3个回答
15
投票

更改您的函数,使其也接受扩展名列表,并用分号或其他分隔符分隔。然后,您可以检查该扩展名列表中每个找到的文件的扩展名是否存在,如果找到,请将其添加到您的字符串列表中。

这样的东西应该有效:

procedure FileSearch(const PathName: string; const Extensions: string;
 var lstFiles: TStringList);
const
  FileMask = '*.*';
var
  Rec: TSearchRec;
  Path: string;
begin
  Path := IncludeTrailingBackslash(PathName);
  if FindFirst(Path + FileMask, faAnyFile - faDirectory, Rec) = 0 then
    try
      repeat
        if AnsiPos(ExtractFileExt(Rec.Name), Extensions) > 0 then
          lstFiles.Add(Path + Rec.Name);
      until FindNext(Rec) <> 0;
    finally
      SysUtils.FindClose(Rec);
    end;

  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, Extensions, lstFiles);
      until FindNext(Rec) <> 0;
    finally
      FindClose(Rec);
    end;
end;

调用示例:

FileSearch('C:\Temp', '.txt;.tmp;.exe;.doc', FileList);

0
投票

在 Delphi XE7 中,这行代码生成(第 17 行)错误:

finally
  SysUtils.FindClose(Rec);
end;

为了纠正错误,我刚刚删除了

SysUtils.
来阅读此代码:

finally
  FindClose(Rec);
end;

现在代码可以正常编译了。感谢您提供这个非常有用的代码和解决方案。


0
投票

因为我无法评论第二个答案,所以我必须写一个新的答案(但它应该被理解为对2的评论!):

例如:Rec.Name="mylib.c", Extensions=".csv;.xls"

然后这个

if AnsiPos(ExtractFileExt(Rec.Name), Extensions) > 0 then
  lstFiles.Add(Path + Rec.Name);

也很匹配!因此,为了避免这种失败,Extensions应该以;结尾,并将代码更改如下:

例如: Rec.Name="mylib.c", Extensions=".csv;.xls;"

if AnsiPos(ExtractFileExt(Rec.Name)+';', Extensions) > 0 then
  lstFiles.Add(Path + Rec.Name);
© www.soinside.com 2019 - 2024. All rights reserved.