Главная страница | назад





Article #23175: Finding all files (or files of a certain type) in a given directory

Question:
Given a directory name, how do I find all files in that directory (or files of a specific type, such as *.jpg)? How to I optionally search through all subdirectories?

Answer:
You can use FindFirst and FindNext functions in SysUtils. Here is an example:

{ procedure GetFiles -
Parameters:
ADirectory: string; // A directory to search for files
Files: TStringList; // The list of files to put the result in
SubFolders: Boolean; // If True, it searches subfolders too }
procedure GetFiles(const ADirectory: string; Files: TStringList; SubFolders: Boolean);
// Helper function to remove any slashes or add them if needed
function SlashSep(const Path, S: string): string;
begin
if AnsiLastChar(Path)^ <> '\' then
Result := Path + '\' + S
else
Result := Path + S;
end;
var
SearchRec: TSearchRec;
nStatus: Integer;
begin
// First find all the files in the current directory 
// You could put something else instead of *.*, such as *.jpeg or *.gif
// to find only files of those types.
nStatus := FindFirst(PChar(SlashSep(ADirectory, '*.*')), 0, SearchRec);
while nStatus = 0 do
begin
Files.Add(SlashSep(ADirectory, SearchRec.Name));
nStatus := FindNext(SearchRec);
end;
FindClose(SearchRec);
// Next look for subfolders and search them if required to do so
if SubFolders then
begin
nStatus := FindFirst(PChar(SlashSep(ADirectory, '*.*')), faDirectory,
SearchRec);
while nStatus = 0 do
begin
// If it is a directory, then use recursion
if ((SearchRec.Attr and faDirectory) <> 0) then
begin
if ( (SearchRec.Name <> '.') and (SearchRec.Name <> '..') ) then
GetFiles(SlashSep(ADirectory, SearchRec.Name), Files, SubFolders);
end;
nStatus := FindNext(SearchRec)
end;
FindClose(SearchRec);
end;
end;

Click here to download the source and sample program from Code Central.

NOTE: Delphi 4's FindClose function has a bug in it and can make this code run in an infinite loop. You will need to change the FindClose function in SysUtils.pas to look like this:


procedure FindClose(var F: TSearchRec);
begin
if F.FindHandle <> INVALID_HANDLE_VALUE then
begin
Windows.FindClose(F.FindHandle);
F.FindHandle := INVALID_HANDLE_VALUE;
end;
end;

Last Modified: 07-NOV-00