Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Directory and its Sub-Directories listing

Posted on 1997-06-10
3
Medium Priority
?
480 Views
Last Modified: 2010-04-06


If I want to get a list of all sub-directories immediately
below a given directory.  

At the moment, I am currently using code like :

     IF FindFirst (in_dir_path + '*.*',
          (faDirectory), SearchRec) = 0 then
     begin
          IF DirectoryExists (in_dir_path + SearchRec.Name) Then
             in_out_Listbox.Items.Add (in_dir_path + SearchRec.Name + '\');
     end;

     While FindNext (SearchRec) = 0 do
     begin
          IF DirectoryExists (in_dir_path + SearchRec.Name) Then
             in_out_Listbox.Items.Add (in_dir_path + SearchRec.Name + '\');
     end;

The real pain is that the FindFirst / FindNext return all files
+ directories - hence the need for the DirectoryExists
check before adding the item to the listbox.

This isn't what I want - because for directories with many hundreds
of files and only a few sub-directories, this takes a few seconds.

Is there any way to list just the directories ?

I have also written code that extends the above to list
all sub-directories of a given directory - not just the directories
immediately below the given directory.

Does anybody have some good fast code to do this ?
0
Comment
Question by:moose032797
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 

Accepted Solution

by:
brittain earned 100 total points
ID: 1336961
Couple things:

1.  FindFirst() and FindNext() are just wrappers around the WINAPI FindFirstFile() and FindNextFile().  The optimal solution would be to write your own FindFirstDir(), etc.

2.  Small performance improvement can be gained by checking the Attr property of SearchRec rather than calling DirectoryExists().

3.  Larger performance improvement:  Build a string list in memory within your loop, then afterwards Assign the string list to the control.  The reason for this is each Items.Add() call sends a Windows message to the control, very slow.
0
 

Author Comment

by:moose032797
ID: 1336962
>The optimal solution would be to write your own
>FindFirstDir(), etc.

OK, but this relies on me being able to find the first dir and
then the next.

As I said above, I need to know how to do this in Delphi.

Moose
0
 

Expert Comment

by:brittain
ID: 1336963
As always, all things are possible with the source.  This is what I meant by write your own.  FindMatchingFile() and FindFirstDir() are straight out of the SYSUTILS.PAS.  (I added the Dir, of course).  The only change is marked by [srb] in the code.  Note, I didn't have to check FindNext()!

This is the quick solution.  These should probably be improved to better exist with SYSUTILS.PAS (i.e. FindMatchingFile() was a local function to the SYSUTILS.PAS unit).

function FindMatchingFile(var F: TSearchRec): Integer;
var
  LocalFileTime: TFileTime;
begin
  with F do
  begin
    while FindData.dwFileAttributes and ExcludeAttr <> 0 do
      if not FindNextFile(FindHandle, FindData) then
      begin
        Result := GetLastError;
        Exit;
      end;
    FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
    FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi,
      LongRec(Time).Lo);
    Size := FindData.nFileSizeLow;
    Attr := FindData.dwFileAttributes;
    Name := FindData.cFileName;
  end;
  Result := 0;
end;


function FindFirstDir(const Path: string; Attr: Integer;
  var F: TSearchRec): Integer;
const
  //[srb]faSpecial = faHidden or faSysFile or faVolumeID or faDirectory;
  //[srb] Added the faAnyFile constant to this exclusion mask!
  faSpecial = faAnyFile or faHidden or faSysFile or faVolumeID or faDirectory;
begin
  F.ExcludeAttr := not Attr and faSpecial;
  F.FindHandle := FindFirstFile(PChar(Path), F.FindData);
  if F.FindHandle <> INVALID_HANDLE_VALUE then
  begin
    Result := FindMatchingFile(F);
    if Result <> 0 then FindClose(F);
  end else
    Result := GetLastError;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  f : TSearchRec;
  lt : TStringList;

begin
  lt := TStringList.Create;
  try
//    if (0 = FindFirst( 'c:\winnt\*.*', (faDirectory), f )) then begin
    if (0 = FindFirstDir( 'c:\winnt\*.*', (faDirectory), f )) then begin
      lt.Add(f.name);
//      while (0 = FindNext( f )) do
      while (0 = FindNext( f )) do
        lt.Add(f.name);

      ListBox1.Items.Assign( lt );
    end;
  finally
    lt.free;
  end;
end;

0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

661 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question