The windows api comes with several functions to search through files in a computer’s filesystem such as FindFirstFile, FindNextFile, … The RTL library in Delphi encapsulates these functions in 3 easy to use functions. These are FindFirst, FindNext and FindClose. Unlike what you may be used to from the win32 api, these functions return 0 not if something went wrong, but if they were successful. You have to pass the function a mask for the files, this consists out of a filemask to search in the current directory or a filemask including a folderpath. An example would be “c:\*”, this would return all files or folders in c:\ depending on what flags you pass to the FindFirst function. Note that the functions are not recursive, so they will only return the content of a folder and not it’s subfolders. The second parameter of the FindFirst function specifies flags that tell the functions what it is searching for. A few flags are faNormal, faHidden, faSysFile, faDirectory, … These can also be combined to select several types of files/directories. The following example shows you how to loop through all files and directories in the c:\ folder:
program FindTest;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
sRec: TSearchRec;
begin
if FindFirst('c:*', faNormal or faDirectory, sRec) = 0 then
begin
repeat
WriteLn(sRec.Name + ' - ' + IntToStr(sRec.Size));
until FindNext(sRec) <> 0;
FindClose(sRec);
end;
ReadLn; // Prevent window from closing
end.
If you would for example change your mask to “c:\*.txt”, it would only return the txt files.
Some of you will also want to be able to recurse this, this can easily be achieved by setting it up in a recursive algoritm:
program FindTest;
{$APPTYPE CONSOLE}
uses
SysUtils;
procedure RecurseFileSystem(const Folder, Mask: string);
var
sRec: TSearchRec;
t: string;
begin
t := IncludeTrailingPathDelimiter(Folder);
if FindFirst(t + Mask, faNormal or faDirectory, sRec) = 0 then
begin
repeat
if ((sRec.Attr and faDirectory) <> 0) and (sRec.Name <> '.') and
(sRec.Name <> '..') then
RecurseFileSystem(t + sRec.Name, Mask)
else
WriteLn(t + sRec.Name + ' - ' + IntToStr(sRec.Size));
until FindNext(sRec) <> 0;
FindClose(sRec);
end;
end;
begin
RecurseFileSystem('c:', '*');
ReadLn; // Prevent window from closing
end.
This example will loop through the entire filesystem on the c drive and show you all of the regular files including their path and size.
Read More