Search for Files via FindFirstFile / FindNextFile - Delphi

DarkCoderSc personal avatar
DarkCoderSc

Jean-Pierre LESUEUR

// ...

uses
  System.SysUtils, Winapi.Windows, Generics.Collections, System.Diagnostics,
  System.RegularExpressions;

// ...

function SearchForFiles(ADirectory : String; var AMatchingFiles : TList<String>; const ARegExPattern : String) : Cardinal;
begin
  if not Assigned(AMatchingFiles) then
    AMatchingFiles := TList<String>.Create();
  ///

  ADirectory := IncludeTrailingPathDelimiter(ADirectory);

  var ASearchParameter := Format('%s*.*', [ADirectory]);

  var AWin32FindData : TWin32FindDataW;

  var hSearch := FindFirstFileW(PWideChar(ASearchParameter), AWin32FindData);
  if (hSearch = INVALID_HANDLE_VALUE) or (hSearch = ERROR_FILE_NOT_FOUND) then
    Exit();
  try
    repeat
      var AFileName := String(AWin32FindData.cFileName);
      if (AFileName = '.') or (AFileName = '..') then
        continue;
      ///

      if AWin32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY then
          SearchForFiles(ADirectory + AFileName, AMatchingFiles, ARegExPattern)
      else begin
        var AMatch := False;

        if String.IsNullOrWhiteSpace(ARegExPattern) then
          AMatch := True
        else if TRegEx.IsMatch(AFileName, ARegExPattern, [roIgnoreCase]) then
          AMatch := True;

        if AMatch then
          AMatchingFiles.Add(ADirectory + AFileName)
      end;
    until FindNextFileW(hSearch, AWin32FindData) = False;

    ///
    result := AMatchingFiles.Count;
  finally
    FindClose(hSearch);
  end;
end;

// ...

begin
  var AMatchingFiles := TList<String>.Create();
  try
    var AStopWatch := TStopWatch.StartNew();

    // Only files ending with 32.dll (PCRE)
    SearchForFiles('c:\Windows\', AMatchingFiles, '.*32\.dll$');

    AStopWatch.Stop();

    if AMatchingFiles.Count = 0 then
      WriteLn('No files found so far with given options.')
    else begin
      WriteLn(Format('Matching Files: %d in %s.', [
        AMatchingFiles.Count,
        AStopWatch.Elapsed.ToString
      ]));

      WriteLn;

      for var AFile in AMatchingFiles do
        WriteLn(AFile);
    end;
  finally
    FreeAndNil(AMatchingFiles);
  end;

// ...

Creating and researching code snippets takes time and effort. You’re welcome to share them through your own platforms, but please don’t forget to credit the original author, here: Jean-Pierre LESUEUR.


Created

May 23, 2025

Last Revised

May 23, 2025