【问题标题】:Efficiently List All Sub-Directories in a Directory有效地列出目录中的所有子目录
【发布时间】:2011-11-09 15:29:33
【问题描述】:

请参阅目前为止所采取的建议编辑...

我正在尝试使用 WinAPI 和 C++ 列出给定目录中的所有目录(文件夹)。

现在我的算法速度慢且效率低:
- 使用 FindFirstFileEx() 打开我正在搜索的文件夹
- 然后我查看目录中的每个文件(使用 FindNextFile());如果它是一个目录文件,那么我将它的绝对路径存储在一个向量中,如果它只是一个文件,我什么也不做。

这似乎效率极低,因为我正在查看目录中的每个文件。

  • 是否有我可以使用的 WinAPI 函数来告诉我给定目录中的所有子目录?
  • 您知道我可以使用一种算法来有效地定位和识别目录(文件夹)中的文件夹吗?

编辑: 因此,在接受了我使用 FindExSearchLimitToDirectories 搜索的建议后,但对我来说,它仍然会打印出所有文件(.txt 等)而不仅仅是文件夹。我做错了吗?

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 );
}

【问题讨论】:

    标签: c++ algorithm file winapi


    【解决方案1】:

    为了提高性能,必须在文件系统级别提供支持。如果不存在,则系统必须枚举目录中的每个对象。

    原则上,您可以使用FindFirstFileEx 指定FindExSearchLimitToDirectories 标志。但是,文档状态(强调我的):

    这是一个建议标志。如果文件系统支持目录过滤,则该函数会搜索与指定名称匹配且也是目录的文件。如果文件系统不支持目录过滤,这个标志会被忽略。

    如果需要目录过滤,这个标志可以在所有文件系统上使用,但是因为它是一个建议标志并且只影响支持它的文件系统,应用程序必须检查存储在 lpFindFileData 中的文件属性数据FindFirstFileEx 函数的参数,以确定该函数是否返回了目录句柄

    但是,据我所知,而且信息很少,FindExSearchLimitToDirectories 标志在桌面文件系统上并未得到广泛支持。

    最好的办法是使用FindFirstFileExFindExSearchLimitToDirectories。如果遇到不支持文件系统级别目录过滤的文件系统,您仍必须执行自己的过滤。如果您很幸运并遇到了支持它的文件系统,那么您将获得性能优势。

    【讨论】:

      【解决方案2】:

      如果您使用FindFirstFileEx,那么您应该能够指定_FINDEX_SEARCH_OPS::FindExSearchLimitToDirectories 选项(用作FindFirstFileEx 中的fSearchOp 参数)来限制第一次搜索(以及任何后续的@987654326 @) 调用目录。

      【讨论】:

      • FindExSearchLimitToDirectories 非常复杂,可能值得在您的答案中指出一些复杂性。此外,我不是 100%,这将导致枚举速度明显加快。过滤是在文件系统级别完成的吗?
      • 根据 MSDN,“如果文件系统支持目录过滤,该函数将搜索具有指定名称的目录。”,所以我假设它是在文件系统级别过滤的。我不确定性能影响 - 我无法对其进行分析,因为我家里没有 Windows 机器。
      • 感谢您的回复,请查看我的编辑,它与您的方法不太匹配
      • FindExSearchLimitToDirectories 仅供参考,因此不能保证您只会获得目录;它只是对支持它的文件系统进行优化。
      • 这很奇怪我有 Windows 7 并且我一年前买了我的笔记本电脑,会优化吗?也许我需要以某种方式启用它?
      猜你喜欢
      • 2018-05-02
      • 2011-11-09
      • 2012-11-14
      • 1970-01-01
      • 2012-09-02
      • 2012-02-12
      • 2020-08-19
      相关资源
      最近更新 更多