12: How to find
the files in a directory AND subdirectories?
A: Writing a program
that goes through the files of the directory,
and all the subdirectories below it, is based on Turbo Pascal's file
finding commands and recursion. This is universal whether you
are
writing, for example, a directory listing program, or a program that
deletes, say, all the .bak files, or some other similar task.
To find (for listing or other purposes) the files in a directory
you need above all the FindFirst and FindNext keywords, and
testing
the predefined file attributes. You make these a procedure, and
call
it recursively. If you want good examples with source code, please
see PC World, April 1989, p. 154; Kent Porter & Mike Floyd
(1990),
Stretching Turbo Pascal. Version 5.5. Revised Edition, Chapter 23;
Michael Yester (1989), Using Turbo Pascal, p. 437; Michael
Tischer
(1992), PC Intern System Programming, pp. 796-798.
The simple (non-recursive) example listing all the read-only
files in the current directory shows the rudiments of the principle
of Using FindFirst, FindNext, and the file attributes, because some
users find it hard to use these keywords. Also see the code in the
item "How to establish if a name refers to a directory or not?
" of
this same FAQ collection you are now reading.
uses Dos;
var FileInfo : SearchRec;
begin
FindFirst ('*.*', AnyFile, FileInfo);
while DosError = 0 do
begin
if (FileInfo.Attr and ReadOnly) > 0 then
writeln (FileInfo.Name);
FindNext (FileInfo);
end;
end. (* test *)
A2: While we are on the
subject related to FindFirst and FindNext,
here are two useful examples:
(* Number of files in a
directory (not counting directories) *)
function DFILESFN (dirName : string) : word;
var nberOfFiles : word;
FileInfo : searchRec;
begin
if dirName[Length(dirName)] <> '\' then dirName := dirName
+ '\';
dirName := dirName + '*.*';
{}
nberOfFiles := 0;
FindFirst (dirName, AnyFile, FileInfo);
while DosError = 0 do
begin
if ((FileInfo.Attr and VolumeId) = 0) then
if (FileInfo.Attr and Directory) = 0 then
Inc (nberOfFiles);
FindNext (FileInfo);
end; {while}
dfilesfn := nberOfFiles;
end; (* dfilesfn *)
(* Number of immediate
subdirectories in a directory *)
function DDIRSFN (dirName : string) : word;
var nberOfDirs : word;
FileInfo : searchRec;
begin
if dirName[Length(dirName)] <> '\' then dirName := dirName
+ '\';
dirName := dirName + '*.*';
{}
nberOfDirs:= 0;
FindFirst (dirName, AnyFile, FileInfo);
while DosError = 0 do
begin
if ((FileInfo.Attr and VolumeId) = 0) then
if (FileInfo.Attr and Directory) > 0 then
if (FileInfo.Name <> '.') and (FileInfo.Name <> '..')
then
Inc (nberOfDirs);
FindNext (FileInfo);
end; {while}
ddirsfn := nberOfDirs;
end; (* ddirsfn *)