Omair Iqbal
Omair Iqbal

Reputation: 1838

Findfirst, findnext listing files but not directories...?

the following code lists files but not directories

var 
rec : tsearchrec;
begin
findfirst('c:\test\*',faanyfile-fadirectory,rec);
        showmessage(rec.Name);
if findnext(rec) <> 0 then close else
showmessage (rec.Name);
end;

Upvotes: 0

Views: 15712

Answers (5)

Remy Lebeau
Remy Lebeau

Reputation: 596417

Read the documentation about how the filter actually works:

The Attr parameter specifies the special files to include in addition to all normal files.

In other words, FindFirst() always returns normal files, regardless of any filter criteria you specify. The Attr parameter merely includes other types of attributes into the base filter. You need to test the TSearchRec.Attr field to determine if a reported entry is actually a file or a directory, eg:

if (rec.Attr and faDirectory) <> 0 then
  // item is a directory
else
  // item is a file

If you implement a recursive search loop, make sure to ignore the "." and ".." directories or else your loop will recurse indefinately:

procedure ScanFolder(const Path: String);
var  
  sPath: string;
  rec : TSearchRec; 
begin 
  sPath := IncludeTrailingPathDelimiter(Path);
  if FindFirst(sPath + '*.*', faAnyFile, rec) = 0 then 
  begin
    repeat
      // TSearchRec.Attr contain basic attributes (directory, hidden,
      // system, etc). TSearchRec only supports a subset of all possible
      // info. TSearchRec.FindData contains everything that the OS
      // reported about the item during the search, if you need to
      // access more detailed information...

      if (rec.Attr and faDirectory) <> 0 then
      begin
        // item is a directory
        if (rec.Name <> '.') and (rec.Name <> '..') then
          ScanFolder(sPath + sr.Name);
      end
      else
      begin
        // item is a file
      end;
    until FindNext(rec) <> 0;
    FindClose(rec);
  end;
end; 

ScanFolder('c:\test');

Upvotes: 8

Francesca
Francesca

Reputation: 21640

  1. You need to NOT exclude the directories, which you unfortunately do with your (-faDirectory)
  2. You have to call FindClose when you're done.
  3. You need to loop if you want to find everything in the directory
var
 rec : tsearchrec;
begin
  if FindFirst('c:\*', faAnyFile, rec) = 0 then
  begin
    repeat
      ShowMessage(rec.Name);
    until FindNext(rec) <> 0;
    FindClose(rec);
  end;
end;

Upvotes: 18

devio
devio

Reputation: 37215

You explicitly excluded directories by stating " - faDirectory" in the flags parameter.

Upvotes: 4

utku_karatas
utku_karatas

Reputation: 6295

What about findfirst('c:\test\*', faanyfile, rec); // not faanyfile-fadirectory

Upvotes: 2

Joe
Joe

Reputation: 42627

If you want all files and directories, just pass in faDirectory to findfirst. It's going to already return you files.

Upvotes: -1

Related Questions