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