Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently List All Sub-Directories in a Directory

Please see edit with advice taken so far...

I am attempting to list all the directories(folders) in a given directory using WinAPI & C++.

Right now my algorithm is slow & inefficient:
- Use FindFirstFileEx() to open the folder I am searching
- I then look at every file in the directory(using FindNextFile()); if its a directory file then I store its absolute path in a vector, if its just a file I do nothing.

This seems extremely inefficient because I am looking at every file in the directory.

  • Is there a WinAPI function that I can use that will tell me all the sub-directories in a given directory?
  • Do you know of an algorithm I could use to efficiently locate & identify folders in a directory(folder)?

EDIT: So after taking the advice I have searched using FindExSearchLimitToDirectories but for me it still prints out all the files(.txt, etc.) & not just folders. Am I doing something wrong?

WIN32_FIND_DATA dirData;
HANDLE dir = FindFirstFileEx( "c:/users/soribo/desktop\\*", FindExInfoStandard, &dirData, 
                              FindExSearchLimitToDirectories, NULL, 0 );

while ( FindNextFile( dir, &dirData ) != 0 )
{
    printf( "FileName: %s\n", dirData.cFileName );
}
like image 885
user593747 Avatar asked Sep 03 '11 07:09

user593747


1 Answers

In order to see a performance boost there must be support at the file system level. If this does not exist then the system must enumerate every single object in the directory.

In principle, you can use FindFirstFileEx specifying the FindExSearchLimitToDirectories flag. However, the documentation states (emphasis mine):

This is an advisory flag. If the file system supports directory filtering, the function searches for a file that matches the specified name and is also a directory. If the file system does not support directory filtering, this flag is silently ignored.

If directory filtering is desired, this flag can be used on all file systems, but because it is an advisory flag and only affects file systems that support it, the application must examine the file attribute data stored in the lpFindFileData parameter of the FindFirstFileEx function to determine whether the function has returned a handle to a directory.

However, from what I can tell, and information is sparse, FindExSearchLimitToDirectories flag is not widely supported on desktop file systems.

Your best bet is to use FindFirstFileEx with FindExSearchLimitToDirectories. You must still perform your own filtering in case you meet a file system that doesn't support directory filtering at file system level. If you get lucky and hit upon a file system that does support it then you will get the performance benefit.

like image 190
David Heffernan Avatar answered Oct 05 '22 08:10

David Heffernan