Board index » delphi » Recursive file search

Recursive file search

Hi,

I wanted to do a file search and write the return results to a file.
Below
is a sample code. But somehow the results return is wrong as it only
shows 'C:\COMMAND.COM'.   If I un-remarked the ShowMessage statement
line, I'm able to see all the correct results. I'm at my wits end why
ShowMessage shows correctly but not the results in the filelist.txt.
I suspect it has got to do with the WriteLn statement.. but where
could I go wrong?

Any help is greatly appreciated.

PROCEDURE GetAllFiles(directory, mask: string);
var
  search: TSearchRec;
  RecFile: TextFile;
begin
  AssignFile(RecFile, 'c:\temp\filelist.txt');
  Rewrite(RecFile);
  if FindFirst(directory + mask, $23, search) = 0 then
  begin
    repeat
      // ShowMessage(directory + search.Name);
      WriteLn(RecFile, directory + search.Name);
    until FindNext(search) <> 0;
  end;

  if FindFirst(directory + '*.*', faDirectory, search) = 0 then
  begin
    repeat
      if ((search.Attr and faDirectory) = faDirectory) and
(search.Name[1] <> '.') then
       GetAllFiles(directory + search.Name + '\', mask);
      until FindNext(search) <> 0;
    FindClose(search);
  end;
    CloseFile(RecFile);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetAllFiles('C:\','*.com');
end;

 

Re:Recursive file search


RonT <too...@singnet.com.sg> schrieb in im Newsbeitrag:
9540eea6.0207070008.126fe...@posting.google.com...
[snip]
Quote
> PROCEDURE GetAllFiles(directory, mask: string);
> var
>   search: TSearchRec;
>   RecFile: TextFile;
> begin
>   AssignFile(RecFile, 'c:\temp\filelist.txt');
>   Rewrite(RecFile);
[snip]
>       if ((search.Attr and faDirectory) = faDirectory) and
> (search.Name[1] <> '.') then
>        GetAllFiles(directory + search.Name + '\', mask);

[snip]

Hi,
every time GetAllFiles is called, the filelist.txt file will be
rewritten, i.e. all its contents is erased. Try to call Rewrite
only once, and write another recursive routine, e.g.
DoGetAllFiles, which does that recursive stuff for you.
Then, write GetAllFiles like this:

procedure GetAllFiles(adirectory, amask: string);
var
  RecFile: TextFile;

  procedure DoGetAllFiles(directory, mask: string);
  begin
// _no_ Rewrite, just append to the opened file
  end;

begin
  AssignFile(RecFile, 'c:\temp\filelist.txt');
  Rewrite(RecFile);
  DoGetAllFiles(adirectory, amask);
// ...
end;

HTH
(
--
Florian Haag
ICQ: 114504497
http://fhaag.de.vu/

Re:Recursive file search


Hi Florian,

Your explanation do help reason out the actual cause.. and it's very
fruitful for beginners like me. After trying your example... I've
managed to get it working.

Once again... thanks a lot!!!!!!!

Rgds
Ron

Quote
"Florian Haag" <florianh...@yahoo.de> wrote in message <news:ag90vg$jog7f$1@ID-83310.news.dfncis.de>...
> RonT <too...@singnet.com.sg> schrieb in im Newsbeitrag:
> 9540eea6.0207070008.126fe...@posting.google.com...
> [snip]
> > PROCEDURE GetAllFiles(directory, mask: string);
> > var
> >   search: TSearchRec;
> >   RecFile: TextFile;
> > begin
> >   AssignFile(RecFile, 'c:\temp\filelist.txt');
> >   Rewrite(RecFile);
>  [snip]
> >       if ((search.Attr and faDirectory) = faDirectory) and
> > (search.Name[1] <> '.') then
> >        GetAllFiles(directory + search.Name + '\', mask);
> [snip]

> Hi,
> every time GetAllFiles is called, the filelist.txt file will be
> rewritten, i.e. all its contents is erased. Try to call Rewrite
> only once, and write another recursive routine, e.g.
> DoGetAllFiles, which does that recursive stuff for you.
> Then, write GetAllFiles like this:

> procedure GetAllFiles(adirectory, amask: string);
> var
>   RecFile: TextFile;

>   procedure DoGetAllFiles(directory, mask: string);
>   begin
> // _no_ Rewrite, just append to the opened file
>   end;

> begin
>   AssignFile(RecFile, 'c:\temp\filelist.txt');
>   Rewrite(RecFile);
>   DoGetAllFiles(adirectory, amask);
> // ...
> end;

> HTH
> (

Re:Recursive file search


Rather than using text file i/o you could collect the results in a string
list and then write them in one operation.

procedure GetAllFiles (const directory, mask : string; results : tStrings);

Quote
> var
>   search: TSearchRec;
> begin
>   if FindFirst(directory + mask, $23, search) = 0 then
>   begin
>     repeat

        results.Add (directory + search.Name);

Quote
>     until FindNext(search) <> 0;
>   end;

>   if FindFirst(directory + '*.*', faDirectory, search) = 0 then
>   begin
>     repeat
>       if ((search.Attr and faDirectory) = faDirectory) and
> (search.Name[1] <> '.') then

           GetAllFiles (directory + search.Name + '\', mask, results);

Quote
>       until FindNext(search) <> 0;
>     FindClose(search);
>   end;
> end;

> procedure TForm1.Button1Click(Sender: TObject);

    var rslt : tStringList;

Quote
> begin

    rslt := tStringList.Create;
    try
        GetAllFiles ('C:\', '*.com', rslt);
    finally
        rslt.SaveToFile ('c:\temp\filelist.txt');
        rslt.Free;
        end;

Quote
> end;

This has the advantage of making GetAllFiles more flexible and hence
reuseable. In testing, for example, one could simply use

        memo1.Clear;
        GetAllFiles ('c:\', '*.com', memo1.Lines);

Re:Recursive file search


Hi Bruce,

Yes... I think your solution is better and more efficient than the
original one I had. Thanks again... it's great to have people like you
and Florian helping others in need...

Rgds
Ron

Quote
"Bruce Roberts" <b...@bounceitattcanada.xnet> wrote in message <news:J_hW8.5424$H67.28404@tor-nn1.netcom.ca>...
> Rather than using text file i/o you could collect the results in a string
> list and then write them in one operation.

> procedure GetAllFiles (const directory, mask : string; results : tStrings);

> > var
> >   search: TSearchRec;

> > begin

> >   if FindFirst(directory + mask, $23, search) = 0 then
> >   begin
> >     repeat

>         results.Add (directory + search.Name);

> >     until FindNext(search) <> 0;
> >   end;

> >   if FindFirst(directory + '*.*', faDirectory, search) = 0 then
> >   begin
> >     repeat
> >       if ((search.Attr and faDirectory) = faDirectory) and
> > (search.Name[1] <> '.') then

>            GetAllFiles (directory + search.Name + '\', mask, results);

> >       until FindNext(search) <> 0;
> >     FindClose(search);
> >   end;

> > end;

> > procedure TForm1.Button1Click(Sender: TObject);

>     var rslt : tStringList;

> > begin

>     rslt := tStringList.Create;
>     try
>         GetAllFiles ('C:\', '*.com', rslt);
>     finally
>         rslt.SaveToFile ('c:\temp\filelist.txt');
>         rslt.Free;
>         end;

> > end;

> This has the advantage of making GetAllFiles more flexible and hence
> reuseable. In testing, for example, one could simply use

>         memo1.Clear;
>         GetAllFiles ('c:\', '*.com', memo1.Lines);

Other Threads