How to Search for Files and Folders with Delphi

Computer in dark office, network lines radiating
Getty Images/Dimitri Otis

When looking for files, it is often useful and necessary to search through subfolders. Here, see how to use Delphi's strength to create a simple, but powerful, find-all-matching-files project.

File/Folder Mask Search Project

The following project not only lets you search for files through subfolders, but it also lets you easily determine file attributes, such as Name, Size, Modification Date, etc. so you can see when to invoke the File Properties Dialog from the Windows Explorer.

In particular, it demonstrates how to recursively search through subfolders and assemble a list of files that match a certain file mask. The technique of recursion is defined as a routine that calls itself in the middle of its code.

In order to understand the code in the project, we have to familiarize ourselves with the next three methods defined in the SysUtils unit: FindFirst, FindNext, and FindClose.

FindFirst

 function FindFirst(const Path: string; Attr: Integer; var Rec: TSearchRec): Integer; 

FindFirst is the initialization call to start a detailed file search procedure using Windows API calls. The search looks for files that match the Path specifier. The Path usually includes wildcard characters (* and ?). Attr parameter contains combinations of file attributes to control the search. The file attribute constants recognized in Attr are: faAnyFile (any file), faDirectory (directories), faReadOnly (read only files), faHidden (hidden files), faArchive (archive files), faSysFile (system files) and faVolumeID (volume ID files).

If FindFirst finds one or more matching files it returns 0 (or an error code for failure, usually 18) and fills in the Rec with information about the first matching file. In order to continue the search, we have to use the same TSearcRec record and pass it to the FindNext function. When the search is completed the FindClose procedure must be called to free internal Windows resources.

The TSearchRec is a record defined as:

 type
 TSearchRec = record
 Time: Integer;
 Size: Integer;
 Attr: Integer;
 Name: TFileName;
 ExcludeAttr: Integer;
 FindHandle: THandle;
 FindData: TWin32FindData;
 end; 

When the first file is found the Rec parameter is filled, and the following fields (values) can be used by your project.
. Attr, the file's attributes as described above.
. Name holds a string that represents a file name, without path information
. Size in bytes of the file found.
. Time stores the file's modification date and time as a file date.
. FindData contains additional information such as the file creation time, last access time, and both the long and short file names.

FindNext

 function FindNext(var Rec: TSearchRec): Integer; 

The FindNext function is the second step in the detailed file search procedure. You have to pass the same search record (Rec) that has been created by the call to FindFirst. The return value from FindNext is zero for success or an error code for any error.

FindClose

 procedure FindClose(var Rec: TSearchRec) ; 

This procedure is the required termination call for a FindFirst/FindNext.

Recursive File Mask Matching Searching in Delphi

This is the "Searching for files" project as it appears at run time.

The most important components on the form are two edit boxes, one list box, a checkbox and a button. Edit boxes are used to specify the path you want to search in and a file mask. Found files are displayed in the List box and if the checkbox is checked then all subfolders are scanned for matching files.

Below is the small code snippet from the project, just to show that searching for files with Delphi is as easy as can be:

 procedure FileSearch(const PathName, FileName : string) ;
 var Rec : TSearchRec;
 Path : string;
 begin
 Path := IncludeTrailingPathDelimiter(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;
 ...
 {all the code, particularly recursive
 function call can be found (downloaded) in
 the project source code}
 ...
 end;