5

I need to get all paths to subfolders within a folder (with WinAPIs and C++.) So far the only solution that I found is recursively calling FindFirstFile / FindNextFile but it takes a significant amount of time to do this on a folder with a deeper hierarchy.

So I was wondering, just to get folder names, is there a faster approach?

ahmd0
  • 16,633
  • 33
  • 137
  • 233
  • 3
    You could try using the indexing service if it is enabled. – Raymond Chen Mar 12 '13 at 01:40
  • @RaymondChen: Do you mean doing my own indexing (like Mahmoud Fayez suggested below)? Or can I reuse the indexing that could've already been done by Windows? – ahmd0 Mar 12 '13 at 04:24
  • 1
    I mean [the built-in one](http://msdn.microsoft.com/en-us/library/aa965362(v=vs.85).aspx). – Raymond Chen Mar 12 '13 at 05:32
  • possible duplicate of [Iterating files in a directory without using FindFirstFile](http://stackoverflow.com/questions/4672040/iterating-files-in-a-directory-without-using-findfirstfile) – Eugene Mayevski 'Callback Mar 12 '13 at 06:11
  • @EugeneMayevski'EldoSCorp: Sorry, that post doesn't give any viable alternatives. I like Raymond's suggestion to use built-in indexing better, or even `FindFirstFileEx` API. Just need to figure out how to implement it... Will post an update when done. – ahmd0 Mar 12 '13 at 16:16
  • Well, there's `NtQueryDirectoryFile`, but I advise against it. `FindFirstFile`/`FindNextFile` is something that's _guaranteed_ to work, but everything else is ... bleh. – Damon Mar 13 '13 at 11:34

3 Answers3

4

If you really just need subfolders you should be able to use FindFirstFileEx with search options to filter out non-directories.

The docs suggest this is an advisory flag only, but your filesystem may support this optimization - give it a try.

FindExSearchLimitToDirectories

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.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
4

A faster approach would be to bypass the FindFirstFile...() API and go straight to the file system directly. You can use DeviceIoControl() with the FSCTL_ENUM_USN_DATA control to access the master file table, at least on NTFS formatted volumes. With that information, you can directly access the records for files/folders, which includes their attributes, parent info, etc. Yes, it would be more work, but it should also be faster since you can optimize the code to access just the pieces you need.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Good idea. The only issue that I envision -- does my process need to run elevated to do that? – ahmd0 Mar 13 '13 at 00:33
2

That is the fastest approach you can come across. Also you may consider using another thread to manage directory enumerations as it takes a lot of time. even Microsoft file explorer spend some time if the directory has a lot of sub folders/files.

One more thing here is that you can enumerate directories once and then register for any updates. so the cost of enumerating the folder should be made only once during start up.

Mahmoud Fayez
  • 3,398
  • 2
  • 19
  • 36