C++列出(LINUX)中的所有目录和子目录

5

我刚学习C++,请问有没有人能给我一些代码,以便在Linux系统中递归获取所有目录及其子目录?我在网上没有找到任何有用的信息或可用的代码。我需要获取指定文件夹及其子文件夹中的所有文件。

在Ubuntu中,我没有获取文件和目录的命令...

6个回答

9

在Linux上尝试这个:

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

void ProcessDirectory(std::string directory);
void ProcessFile(std::string file);
void ProcessEntity(struct dirent* entity);

std::string path = "/path/to/directory/";

int main()
{
    std::string directory = "theDirectoryYouWant";
    ProcessDirectory(directory);    

    return 0;
}

void ProcessDirectory(std::string directory)
{
    std::string dirToOpen = path + directory;
    auto dir = opendir(dirToOpen.c_str());

    //set the new path for the content of the directory
    path = dirToOpen + "/";

    std::cout << "Process directory: " << dirToOpen.c_str() << std::endl;

    if(NULL == dir)
    {
        std::cout << "could not open directory: " << dirToOpen.c_str() << std::endl;
        return;
    }

    auto entity = readdir(dir);

    while(entity != NULL)
    {
        ProcessEntity(entity);
        entity = readdir(dir);
    }

    //we finished with the directory so remove it from the path
    path.resize(path.length() - 1 - directory.length());
    closedir(dir);
}

void ProcessEntity(struct dirent* entity)
{
    //find entity type
    if(entity->d_type == DT_DIR)
    {//it's an direcotry
        //don't process the  '..' and the '.' directories
        if(entity->d_name[0] == '.')
        {
            return;
        }

        //it's an directory so process it
        ProcessDirectory(std::string(entity->d_name));
        return;
    }

    if(entity->d_type == DT_REG)
    {//regular file
        ProcessFile(std::string(entity->d_name));
        return;
    }

    //there are some other types
    //read here http://linux.die.net/man/3/readdir
    std::cout << "Not a file or directory: " << entity->d_name << std::endl;
}

void ProcessFile(std::string file)
{
    std::cout << "Process file     : " << fileToOpen.c_str() << std::endl;

    //if you want to do something with the file add your code here
}

4

递归是不必要的。Linux 上有一种迭代的方法可以做到这一点。

#include <ftw.h>

int ftw(const char *dirpath,
        int (*fn) (const char *fpath, const struct stat *sb,
                   int typeflag),
        int nopenfd);
< p > ftw() 函数遍历给定目录树中的每个文件和目录,并调用提供的回调函数。 < /p >

3
Windows: 这里提供了关于在Windows上列出目录中所有文件的相关信息。
Unix/Linux: 可以参考这个链接,了解如何在Unix/Linux系统上列出指定目录中的所有文件。
对于指定的目录,需要递归地应用相同的算法。

2
使用nftw,它提供了各种选项来微调目录遍历。该页面还展示了一个示例

2

除了Dmitri的回答之外,您可能会对使用nftw库函数感兴趣,该函数可以“为您递归”。


0

关于列出目录的答案只是回答的第一部分,但我没有看到任何人回答递归部分。要递归地执行任何操作,您必须创建一个“调用自身”的子程序--请注意,在处理符号链接时应格外小心,尤其是在使用nfs时,例如/exports,可能会导致循环递归并将您锁定在无限循环中!基本上:

这不是真正的代码,它是伪代码,旨在帮助您更好地理解递归的工作原理,而不会用语言使您感到困惑。这个思想可以应用于任何具有某种调用-返回机制的语言,这些天几乎是我所能想到的每种语言。

// PSEUDO-CODE
stiring entriesarray[] myfunc(string basedir)
{
  string results[] = getfilesandfolders(basedir) // you might want to specify a filter
  for each string entry in results
  {
        // if you want only files you'll need to test for if entry is a file
       entriesarray.add(entry)
       if (entry is a directory && entries is not a symbolic link)
       {
            string moreentriesarray[] = myfunc(entry)
            entriesarray.join(moreentriesarray)
       }
  }
  return entriesarray[]
}

注意,如果条目不包含任何真实目录,则函数不会调用自身。这很重要,因为这是避免无限递归的方法。但请注意,您可能希望使此操作可以取消,因为现在的大型文件系统需要花费很长时间来处理。我通常的做法是启动另一个线程,在后台进行搜索,并让后台线程检查取消标志以便用户可以停止操作,并且它可以发布有关剩余时间、完成百分比等信息。虽然有点粗糙,但这应该可以让任何对此感兴趣的人朝着正确的方向前进。并且请记住,始终要正确检查错误并放置异常处理,这是我看到新程序员总是忽略的事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接