【问题标题】:Recursive file search using C++ MFC?使用 C++ MFC 进行递归文件搜索?
【发布时间】:2009-05-27 17:12:36
【问题描述】:

使用 C++ 和 MFC 递归搜索文件的最简洁方法是什么?

编辑:这些解决方案中的任何一个都提供通过一次通过使用多个过滤器的能力吗?我想用 CFileFind 我可以过滤 *.* 然后编写自定义代码以进一步过滤到不同的文件类型。有没有提供内置的多个过滤器(即*.exe、*.dll)?

EDIT2:刚刚意识到我所做的一个明显假设使我之前的 EDIT 无效。如果我尝试使用 CFileFind 进行递归搜索,我必须使用 *.* 作为我的通配符,否则子目录将不会匹配并且不会发生递归。所以过滤不同的文件扩展名必须单独处理。

【问题讨论】:

  • CFileFind 类只是 FindFirstFile 和 FindNextFile Windows API 函数的一个薄包装器。这些没有为多个通配符提供任何规定。

标签: c++ mfc recursion file-search


【解决方案1】:

使用CFileFind

看看这个来自 MSDN 的example

void Recurse(LPCTSTR pstr)
{
   CFileFind finder;

   // build a string with wildcards
   CString strWildcard(pstr);
   strWildcard += _T("\\*.*");

   // start working for files
   BOOL bWorking = finder.FindFile(strWildcard);

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

      // skip . and .. files; otherwise, we'd
      // recur infinitely!

      if (finder.IsDots())
         continue;

      // if it's a directory, recursively search it

      if (finder.IsDirectory())
      {
         CString str = finder.GetFilePath();
         cout << (LPCTSTR) str << endl;
         Recurse(str);
      }
   }

   finder.Close();
}

【讨论】:

    【解决方案2】:

    使用Boost's Filesystem 实现!

    递归示例甚至在文件系统主页上:

    bool find_file( const path & dir_path,         // in this directory,
                    const std::string & file_name, // search for this name,
                    path & path_found )            // placing path here if found
    {
      if ( !exists( dir_path ) ) return false;
      directory_iterator end_itr; // default construction yields past-the-end
      for ( directory_iterator itr( dir_path );
            itr != end_itr;
            ++itr )
      {
        if ( is_directory(itr->status()) )
        {
          if ( find_file( itr->path(), file_name, path_found ) ) return true;
        }
        else if ( itr->leaf() == file_name ) // see below
        {
          path_found = itr->path();
          return true;
        }
      }
      return false;
    }
    

    【讨论】:

      【解决方案3】:

      我知道这不是你的问题,但使用 CStringArray 也很容易无需递归

      void FindFiles(CString srcFolder)
      {   
        CStringArray dirs;
        dirs.Add(srcFolder + "\\*.*");
      
        while(dirs.GetSize() > 0) {
           CString dir = dirs.GetAt(0);
           dirs.RemoveAt(0);
      
           CFileFind ff;
           BOOL good = ff.FindFile(dir);
      
           while(good) {
              good = ff.FindNextFile();
              if(!ff.IsDots()) {
                if(!ff.IsDirectory()) {
                   //process file
                } else {
                   //new directory (and not . or ..)
                   dirs.InsertAt(0,nd + "\\*.*");
                }
              }
           }
           ff.Close();
        }
      }
      

      【讨论】:

      • @ahoo 哎呀。怀疑我可以很容易地找到我的代码,但nd 来自ff.GetFileName()ff.GetFilePath()。因此,在每次迭代中,您将所有找到的目录添加到 dirs 列表中。 CFileFind
      【解决方案4】:

      查看recls 库 - 代表 recursive ls - 这是一个适用于 UNIX 和 Windows 的递归搜索库。它是一个 C 库,可以适应不同的语言,包括 C++。从记忆中,您可以像下面这样使用它:

      using recls::search_sequence;
      
      
      CString dir = "C:\\mydir";
      CString patterns = "*.doc;abc*.xls";
      CStringArray paths;
      search_sequence files(dir, patterns, recls::RECURSIVE);
      
      for(search_sequence::const_iterator b = files.begin(); b != files.end(); b++) {
          paths.Add((*b).c_str());
      }
      

      它将在 C:\mydir 或其任何子目录中找到所有 .doc 文件和所有以 abc 开头的 .xls 文件。

      我还没有编译这个,但它应该很接近标记。

      【讨论】:

        【解决方案5】:
        CString strNextFileName , strSaveLog= "C:\\mydir";
        Find.FindFile(strSaveLog);
        BOOL l = Find.FindNextFile();
        if(!l)
            MessageBox("");
        strNextFileName = Find.GetFileName();
        

        它不工作。即使文件存在于同一目录中,Find.FindNextFile() 也会返回 false

        【讨论】:

        • 也许您需要在路径中添加通配符? strSaveLog = "C:\\mydir\*.*"。另外,不要在应该回答的地方问问题!
        猜你喜欢
        • 2012-01-30
        • 2021-04-20
        • 1970-01-01
        • 1970-01-01
        • 2016-01-19
        • 1970-01-01
        • 2010-09-20
        • 2018-07-08
        相关资源
        最近更新 更多