Enumerate Files via FindFirstFile / FindNextFile - Delphi
 
        DarkCoderSc
Jean-Pierre LESUEUR
// ...
uses
  System.SysUtils, Winapi.Windows, Generics.Collections;
// ...
(* TFileEnumerationSummary *)
type
  TFileEnumerationSummary = record
    FileCount      : Cardinal;
    DirectoryCount : Cardinal;
    {@M}
    function GetTotal() : Cardinal;
    {@I}
    class operator Initialize(out ADest: TFileEnumerationSummary);
    {@G}
    property Total : Cardinal read GetTotal;
  end;
class operator TFileEnumerationSummary.Initialize(out ADest: TFileEnumerationSummary);
begin
  ADest.FileCount := 0;
  ADest.DirectoryCount := 0;
end;
function TFileEnumerationSummary.GetTotal() : Cardinal;
begin
  result := FileCount + DirectoryCount;
end;
// ...
(* Local *)
// ...
function EnumerateFiles(ADirectory : String; var AFiles : TList<String>; var ADirectories : TList<String>; const ARecursive : Boolean = False) : TFileEnumerationSummary;
  procedure InitializeList(var AList : TList<String>);
  begin
    if not Assigned(AList) then
      AList := TList<String>.Create()
    else if not ARecursive then
      AList.Clear();
  end;
begin
  ADirectory := IncludeTrailingPathDelimiter(ADirectory);
  InitializeList(AFiles);
  InitializeList(ADirectories);
  var ASearchParameter := Format('%s*.*', [ADirectory]);
  var AWin32FindData : TWin32FindDataW;
  var hSearch := FindFirstFileW(PWideChar(ASearchParameter), AWin32FindData);
  if hSearch = INVALID_HANDLE_VALUE then
    raise EWindowsException.Create('FindFirstFileW')
  else if hSearch = ERROR_FILE_NOT_FOUND then
    raise Exception.Create(Format('No files found so far in the directory: `%s`', [ADirectory]));
  try
    repeat
      var AFileName := String(AWin32FindData.cFileName);
      if (AFileName = '.') or (AFileName = '..') then
        continue;
      ///
      if AWin32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY then begin
        ADirectories.Add(ADirectory + AFileName);
        if ARecursive then
          EnumerateFiles(ADirectory + AFileName, AFiles, ADirectories, ARecursive);
      end else
        AFiles.Add(ADirectory + AFileName);
    until FindNextFileW(hSearch, AWin32FindData) = False;
    ///
    result.FileCount := AFiles.Count;
    result.DirectoryCount := ADirectories.Count;
  finally
    FindClose(hSearch);
  end;
end;
// ...
begin
  var AFiles := TList<String>.Create();
  var ADirectories := TList<String>.Create();
  try
    var ASummary := EnumerateFiles('c:\Temp', AFiles, ADirectories, True);
    WriteLn(Format('Directories: %d, Files: %d - [Total: %d]', [
      ASummary.DirectoryCount,
      ASummary.FileCount,
      ASummary.Total
    ]));
    WriteLn;
    for var ADirectory in ADirectories do
      WriteLn(ADirectory);
    for var AFile in AFiles do
      WriteLn(AFile);
  finally
    FreeAndNil(ADirectories);
    FreeAndNil(AFiles);
  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.
Depends On
Implemented By Technique
Featured Windows APIs
Created
May 23, 2025
Last Revised
May 23, 2025
 File System Enumeration
                                            File System Enumeration