2

我发现了很多关于遍历目录树的例子,但我需要一些不同的东西。我需要一个带有某种方法的类,每次调用从目录中返回一个文件并逐渐遍历目录树。请问我该怎么做?我正在使用函数 FindFirstFile、FindNextFile 和 FindClose,我是 C++ 的新手。我有这样的东西...

例如我有这个简单的目录树

Parent(folder)\
   file1.txt
   file2.txt
   Child(folder)\
       file3.txt
       file4.txt

我需要一个带有方法的类,例如getNextFile(),第一次调用返回file1.txt;第二次调用返回file2.txt,第三次调用返回Child(文件夹),第四次调用返回file3.txt,依此类推...

编辑重复标志:我基本上需要遍历树而不使用 do/while、while 或 for...理想情况下仅使用 winapi 调用

WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;
if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
    return false;
}
do
{
    //do some job with fdFile
}
while(FindNextFile(hFind, &fdFile));
4

2 回答 2

4

这是在 Windows 平台上执行此操作的本机 C++ 方式(使用 MFC 框架):

void ListFiles(const CString& sPath)
{
   CFileFind finder;

   CString sWildcard(sPath);
   sWildcard += _T("\\*.*");

   BOOL bWorking = finder.FindFile(sWildcard);

   while (bWorking)
   {
      bWorking = finder.FindNextFile();

      if (finder.IsDots())
         continue;

      if (finder.IsDirectory())
      {
         CString sFilePath = finder.GetFilePath();
         // TODO: do stuff here
         ListFiles(sFilePath);
      }
   }

   finder.Close();
}

您可以更改通配符字符串以针对特定文件,例如*.txt等。您也可以将其作为参数传递给此函数以使其更通用。

于 2015-04-10T08:54:32.277 回答
2

使用正确的工具。Boost 随处可用,并且具有您想要的方法。

来自http://rosettacode.org/wiki/Walk_a_directory/Recursively#C.2B.2B

#include "boost/filesystem.hpp"
#include "boost/regex.hpp"
#include <iostream>

using namespace boost::filesystem;

int main()
{
  path current_dir("."); //
  boost::regex pattern("a.*"); // list all files starting with a
  for (recursive_directory_iterator iter(current_dir), end;
       iter != end;
       ++iter)
  {
    std::string name = iter->path().filename().string();
    if (regex_match(name, pattern))
      std::cout << iter->path() << "\n";
  }
}

如果您不关心您的文件是否与某个模式匹配,请删除整个正则表达式业务。

编辑:

您能否解释一下为什么直接使用 API 调用会不好?

  1. 它丑陋且难以阅读,更难正确,
  2. 它根本不便携,最重要的是,
  3. 在使用原始 win api 时,您可能需要处理一百万个极端情况。Boost 是由这样做了几百次的人编写的,并且经过了认真的代码审查,所以请走保存路线,不要重新发明轮子。

本质上,winapi 大约有 20 年的历史;在世界其他地方,可用性得到了很大的改进。除非您有充分的理由,否则我会尝试使用常用库(例如 Boost)尽可能多地抽象它。

我认为这并不能解决我的问题,我编辑了原始帖子以使其更清晰。

基本上需要在没有do/while,while或for的情况下遍历树...我需要某种迭代器,可以存储以备后用

这正是我的回答所做的:在 for 循环中给你一个迭代器。我不明白什么不符合您的编辑规范。

此外,最好只使用 WinAPI,因为它必须在不同的带有 Windows 的计算机上工作,并且安装 boost 可能是个问题。

您不必在任何这些计算机上安装 boost。Boost::filesystem 可以轻松地静态链接;此外,老式的 Windows 方法只是交付boost_filesystem*.dllboost_system*.dll与您的二进制文件一起交付。但是,如果您的目标是包含所有需要的功能的单个可执行文件,那么无论如何您都会选择静态链接,所以这绝对没有问题。

于 2015-04-10T08:02:34.650 回答