如何快速枚举Win32上的目录?

Bil*_*eal 26 c++ winapi

我正在尝试加速C++中的目录枚举,我正在递归到子目录.我目前有一个应用程序花费95%的时间在FindFirst/FindNextFile API中,并且需要几分钟来枚举给定卷上的所有文件.我知道有可能更快地做到这一点,因为有一个应用程序可以做到:一切.它可以在几秒钟内枚举我的整个驱动器.

我怎么能做到这样的事情?

小智 8

我意识到这是一个老帖子,但是有一个关于源伪造的项目,它正是你所要求的,并且源代码可用.

你可以在这里找到这个项目:NTFS-Search


Mic*_*urr 6

"Everything"以低于Win32 FindFirst/FindNext API的级别访问目录信息.

我相信它直接读取和解释NTFS MFT结构,这是其性能的主要原因之一.这也是为什么它需要管理员权限以及为什么"Everything"仅索引本地或可移动NTFS卷(例如,不是网络驱动器)的原因.

其他几个执行类似操作的实用程序是:

使用这些工具上的调试器进行一点反向工程可能会让您对他们使用的技术有所了解.

  • @BillyONeal:我能理解这两点.另外 - 您不一定需要深入研究汇编语言来获取信息.像Dependency Walker(http://www.dependencywalker.com/)和Process Monitor(http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx)这样的工具可以告诉你很多关于API的信息.程序使用时不会一直潜入拆卸.使用这些工具是否违反EULA是我无法告诉您的. (3认同)

Mar*_*som 5

不要立即递归,保存找到的目录列表,并在完成后深入研究它们。您希望对每个目录进行线性访问,以利用引用的局部性和操作系统正在执行的任何缓存。


pet*_*hen 5

"Everything"在后台构建索引,因此查询针对索引而不是文件系统本身.

有一些改进 - 至少在直接的算法上:

首先,广度搜索深度搜索.也就是说,在递归到您找到的子文件夹之前,枚举并处理单个文件夹中的所有文件.这改善了地方 - 通常很多.

在Windows 7/W2K8R2,您可以使用FindFirstFileExFindExInfoBasic,主要是加速省略这个地方启用NTFS文件系统上的短文件名.

如果枚举不同的物理磁盘(不仅仅是驱动器),单独的线程会有所帮助.对于同一磁盘,只有它是SSD("零搜索时间"),或者您花费大量时间处理文件名(与磁盘访问所花费的时间相比)才有用.


[编辑] 维基百科实际上有一些评论 - 基本上,他们正在跳过文件系统抽象层,并直接访问NTFS.这样,他们可以批量调用并跳过文件系统的昂贵服务 - 例如检查ACL.

一个很好的起点是MSDN上的NTFS技术参考.