用于列出子目录中所有文件的递归函数

时间:2012-10-29 20:43:53

标签: c++

我正在尝试编写一个函数,该函数返回当前文件夹及其所有子文件夹中所有文件的列表。我写了这段代码:

#include <iostream>
#include <dirent.h>
#include <cstring>

using namespace std;

int main() {
   DIR* dir; dirent* pdir;
   //From my workspace
   dir=opendir(".");     
   while (pdir=readdir(dir)) {
       if(/**********This pdir is a directory**********/) {
           /**********RECURSIVE CALL SHOULD BE HERE**********/
           cout<<pdir->d_name<<endl;
       }
   }
   closedir(dir);
   return 0;
}

我在谷歌搜索它,我不知道如何:

  • 检查当前pdir是否为目录
  • 进入目录并对其执行递归调用

同时我将所有东西都放在main上,因为我仍然不知道递归函数应该有什么参数。

任何提示?

8 个答案:

答案 0 :(得分:9)

这是使用建议的标准文件系统库的版本:

#include <iostream>
#include <filesystem>

using namespace std;
using namespace std::tr2::sys;

void main()
{   
  for (recursive_directory_iterator i("."), end; i != end; ++i) 
    if (!is_directory(i->path()))
      cout << i->path().filename() << "\n";
} 

答案 1 :(得分:8)

除非您的目标是学习如何编写递归函数,否则您可能更喜欢基于Boost.Filesystem的简单循环:

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

int main () {
  for ( boost::filesystem::recursive_directory_iterator end, dir("./");
    dir != end; ++dir ) {
    // std::cout << *dir << "\n";  // full path
    std::cout << dir->path().filename() << "\n"; // just last bit
  }
}

甚至单个函数调用:

std::copy(
  boost::filesystem::recursive_directory_iterator("./"),
  boost::filesystem::recursive_directory_iterator(),
  std::ostream_iterator<boost::filesystem::directory_entry>(std::cout, "\n"));

答案 2 :(得分:5)

在将基目录路径作为参数的过程中隔离该代码,以便您可以实际执行递归调用。它应该像

void recursive_file_list(const char * directory)
{
    // ...
}

然后,要检查您获得的pdir是否是目录,您有两条路线:

  • 您可以查看pdir->d_type==DT_DIR;这会立即为您提供此信息,但它不可移植(POSIX不强制存在d_type成员);此外,它不支持所有文件系统,因此您可能会获得DT_UNKNOWN。如果您想要遵循符号链接,如果获得DT_LNK,还必须执行额外的检查。在这些情况下,您必须回退到lstat(请参阅下面的内容);
  • 您可以移植使用lstat来获取有关每个文件的信息,特别选中st_mode的{​​{1}}字段。

答案 3 :(得分:3)

我在C ++ 11中的方法:

#include <string>
#include <functional>
#include <dirent.h>

void listFiles(const std::string &path, std::function<void(const std::string &)> cb) {
    if (auto dir = opendir(path.c_str())) {
        while (auto f = readdir(dir)) {
            if (!f->d_name || f->d_name[0] == '.') continue;
            if (f->d_type == DT_DIR) 
                listFiles(path + f->d_name + "/", cb);

            if (f->d_type == DT_REG)
                cb(path + f->d_name);
        }
        closedir(dir);
    }
}

用法:

listFiles("my_directory/", [](const std::string &path) {
    std::cout << path << std::endl;
});

答案 4 :(得分:1)

路径应该看起来像fgets()。要在隐藏文件夹中搜索,您应该添加第三个参数/your_path/

true

答案 5 :(得分:0)

您可以检查是否没有“。”在字符串中。

if(strstr(pdir->d_name,".") != NULL)

答案 6 :(得分:0)

使用C ++ 17 recursive_directory_iterator变得非常简洁:

void ls_recursive(const std::filesystem::path& path) {
    for(const auto& p: std::filesystem::recursive_directory_iterator(path)) {
        if (!std::filesystem::is_directory(p)) {
            std::cout << p.path() << '\n';
        }
    }
}

输出示例:

"/home/user/prj/rust/stack/Cargo.toml"
"/home/user/prj/rust/stack/.gitignore"
"/home/user/prj/rust/stack/src/main.rs"
"/home/user/prj/rust/stack/.git/config"

答案 7 :(得分:0)

这是我的用法

std::vector<std::string> get_all_files_recursive(const fs::path& path)
    {
        std::vector<std::string> result;

        for (const auto& p : fs::recursive_directory_iterator(path))
        {
            if (!fs::is_directory(p))
            {
                fs::path path = p.path();
                result.push_back(path.u8string());
            }
        }

        return result;
    }