用于列出子目录中所有文件的递归功能
Recursive function for listing all files in sub directories
我正在尝试编写一个函数,该函数返回当前文件夹及其所有子文件夹上的所有文件列表。我写了此代码:
#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;
}
我在Google中搜索了它,但我不知道如何:
- 检查当前
pdir
是否是目录 - 进入目录内,对其进行递归调用
与此同时,我的所有内容都在主上,因为我仍然不知道递归函数应该具有什么参数。
有任何提示?
这是一个使用建议的标准文件系统库的版本:
#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";
}
我在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;
});
,除非您的目标是学习如何编写递归功能,否则您可能会基于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"));
在以基本目录路径为参数的过程中隔离该代码,因此您可以实际执行递归调用。它应该像
void recursive_file_list(const char * directory)
{
// ...
}
然后,要检查您获得的pdir
是否是目录,您有两条路线:
- 您可以检查
pdir->d_type==DT_DIR
;这立即为您提供此信息,但它不是便携式的(POSIX并不要求d_type
成员的存在);另外,它不支持所有文件系统,因此您可能会获得DT_UNKNOWN
。如果您想遵循Symlinks,则必须执行额外的检查,如果您获得DT_LNK
。在这些情况下,您必须回到lstat
(请参阅下点); - 您可以随时使用
lstat
获取有关每个文件的信息,特别是检查st_mode
的CC_9字段。
使用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"
它使用标准C 功能。无需在代码中包括任何第三方库。
仅将目录路径作为参数发送。它会将其归还该文件夹及其子文件夹中的每个文件路径。
此外,如果您需要对任何特定类型的文件(即.txt或.jpg)进行分类,请通过扩展名,它将打印所有具有相应扩展名的文件路径。
#include <Windows.h>
#include<iostream>
#include<vector>
#include<string>
using namespace std;
vector<string> files;
std::string Recursive(std::string folder) {
std::string search_path = folder + "/*.*";
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(search_path.c_str(), &fd);
std::string tmp;
if (hFind != INVALID_HANDLE_VALUE) {
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (!(!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, ".."))) {
tmp = folder + "\";
tmp = tmp + fd.cFileName;
Recursive(tmp);
}
}
else {
std::string FinalFilePath = folder + "\" + fd.cFileName;
files.push_back(FinalFilePath);
}
} while (::FindNextFile(hFind, &fd));
::FindClose(hFind);
}
return folder;
}
bool has_suffix(const std::string& str, const std::string& suffix) {
return str.size() >= suffix.size() &&
str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}
int main(){
std::string folder = "C:\Users\Omkar\Desktop\Test";
Recursive(folder);
std::string t;
const auto needle = std::string(".txt");
while (!files.empty()) {
t = files.back();
if (has_suffix(t, ".mmt")) {
cout << "FINAL PATH : " << t << endl;
t.clear();
}
files.pop_back();
}
return 0;
}
路径应看起来像/your_path/
。对于隐藏文件夹内的搜索,您应该添加第三参数true
。
#include <dirent.h>
#include <vector>
#include <cstring>
void GetReqDirs(const std::string& path, std::vector<string>& files,const bool showHiddenDirs = false){
DIR *dpdf;
struct dirent *epdf;
dpdf = opendir(path.c_str());
if (dpdf != NULL){
while ((epdf = readdir(dpdf)) != NULL){
if(showHiddenDirs ? (epdf->d_type==DT_DIR && string(epdf->d_name) != ".." && string(epdf->d_name) != "." ) : (epdf->d_type==DT_DIR && strstr(epdf->d_name,"..") == NULL && strstr(epdf->d_name,".") == NULL ) ){
GetReqDirs(path+epdf->d_name+"/",files, showHiddenDirs);
}
if(epdf->d_type==DT_REG){
files.push_back(path+epdf->d_name);
}
}
}
closedir(dpdf);
}
您可以检查是否没有"。在字符串中。
if(strstr(pdir->d_name,".") != NULL)
在这里我如何使用
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;
}
很棒的东西!这是我的Windows友好解决方案使用STD,因为我在Windows上的上述解决方案很少有bump,也可以在DLL中使用:
: #include <windows.h> // messagebox
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <filesystem> // C++17 standard header file name
#include <experimental/filesystem> // Header file for pre-standard implementation
using namespace std::experimental::filesystem::v1;
for (recursive_directory_iterator next(path(dir.c_str())), end; next != end; ++next)
{
auto path = next->path();
if (path.has_extension())
{
MessageBox(0, path.wstring().c_str(), L"Filepath", 0);
}
}
一种简单的方法是基于C。它使用dirent
列出文件/文件夹,而stat
用于获取文件/文件夹信息。
然后,您会回忆起功能,如果资源为目录。
请注意,您无法在.
(当前文件夹实例)和..
(Parent Folder实例)上递归致电
此以下代码为您提供了一个想法。优势是能够在大多数版本的C 上工作。
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
void printdir(std::string dirname)
{
DIR *dir;
struct dirent *ent;
if ((dir = opendir (dirname.c_str())) != NULL)
{
/* print all the files and directories within directory and sub-directories */
while ((ent = readdir (dir)) != NULL)
{
struct stat s;
std::string path = dirname + "\" + ent->d_name;
std::cout << path << " ";
if(stat(path.c_str(), &s) == 0)
{
if(s.st_mode & S_IFDIR)
{
//it's a directory
std::cout << "(directory)" << std::endl;
//don't call recursively for . and ..
if(std::string(ent->d_name) != "." && std::string(ent->d_name) != "..")
{
printdir(path);
}
}
else if(s.st_mode & S_IFREG)
{
//it's a file
std::cout << "(file)" << std::endl;
}
else
{
std::cout << "(unknow)" << std::endl;
//something else
}
}
else
{
//error
std::cout << "(error)" << std::endl;
}
}
closedir (dir);
}
else
{
/* could not open directory */
perror ("");
}
}
int main()
{
std::string dirname(".");
printdir(dirname);
return 0;
}
- 递归计数给定目录的文件和所有目录
- 包含模板文件的递归会导致编译失败
- 递归地将FEATURE_FLAG导出到生成文件、CPP 和头文件
- 如何递归复制文件和目录
- 使用FindFirstFile和FindNextFile递归查找具有特定扩展名的文件
- boost::文件系统递归获取每个文件的大小
- C++ 源代码的递归生成文件
- 问题 - 递归函数以返回文本文件排列
- 使用C 列出目录中的文件,而不是递归,只有文件和无子目录
- 列出MFC错误中递归运行的所有文件
- 同一生成文件中的 make 目标之间的递归依赖关系
- 递归递归文件
- 递归扫描目录中的文件
- 使用boost递归地将给定目录中每个最低级别文件夹的文件复制到另一个目录-C++
- 输入所有子文件夹 - 递归
- 用于列出子目录中所有文件的递归功能
- 使用递归获取某个目录中的所有文件
- Qt vs Boost 文件系统递归文件计数
- 如何用C++递归地从二进制文件中读取自定义字符串
- 在Qt中递归浏览目录,跳过文件夹"."并".."