[英]Find all files in all directories in c++
I am trying to find all files in all directories, but I don't know how to handle subdirectories. 我正在尝试查找所有目录中的所有文件,但是我不知道如何处理子目录。 In this code, the code looks trough all subdirs, but I don't know how to jump back. 在这段代码中,代码看起来遍历所有子目录,但我不知道如何跳回。 Does anyone know how to do this? 有谁知道如何做到这一点?
__declspec(dllexport) void GetFiles(char* filedir, char* path)
{
string s[1000];
string path2 = path;
UINT index = 0;
WIN32_FIND_DATA ffd;
TCHAR szDir[MAX_PATH];
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
StringCchCopy(szDir, MAX_PATH, filedir);
if (INVALID_HANDLE_VALUE == hFind)
return;
do
{
DWORD attributes = ffd.dwFileAttributes;
if (attributes & FILE_ATTRIBUTE_HIDDEN)
continue;
else if (attributes & FILE_ATTRIBUTE_DIRECTORY)
{
TCHAR dir2[MAX_PATH];
path2 = path;
path2 += ffd.cFileName;
path2 += "\\*";
StringCchCopy(dir2, MAX_PATH, path2.c_str());
SetCurrentDirectory(dir2);
}
else
{
s[index] = path;
s[index] += ffd.cFileName;
index++;
}
}
while (FindNextFile(hFind, &ffd) >= 0); // needs to jump back if zero
FindClose(hFind);
}
EDIT: functions had the same name which confused the compiler 编辑:函数具有混淆编译器的相同名称
I think the easiest way to do it is by doing a recursive function. 我认为最简单的方法是执行递归函数。
This would roughly look like something like this in "c" pseudo code 这大致类似于“ c”伪代码中的内容
void GetFiles( char*** file_path_table, char* dir )
{
char **file_paths;
file_paths = getAllFiles( dir );
foreach( path in file_paths )
{
if ( is_directory( path ) )
{
GetFiles( file_path_table, path );
}
else
{
add_file_to_table( file_path_table, path );
}
}
}
Instead of changing directory via SetCurrentDirectory()
use a recursive call on GetFiles()
. 代替通过SetCurrentDirectory()
更改目录,请对GetFiles()
进行递归调用。 This would require that the caller pass in a reference to an array (or std::vector<std::string>
) for the list of files to be stored in instead of using the local array s
. 这将要求调用者传递对要存储文件列表的数组(或std::vector<std::string>
)的引用,而不是使用本地数组s
。
Doing a bit of searching through old posts, I guess I've mentioned doing a breadth-first search a number of times, but never really posted code to show how to do it. 在旧帖子中进行一些搜索,我想我已经提到过多次进行广度优先搜索,但是从未真正发布过代码来展示如何做。 I guess I might as well do that. 我想我也应该这样做。
#include <windows.h>
#include <queue>
#include <string>
#include <iostream>
// I think MS's names for some things are obnoxious.
const HANDLE HNULL = INVALID_HANDLE_VALUE;
const int A_DIR = FILE_ATTRIBUTE_DIRECTORY;
// We'll process a file by printing its path/name
void process(std::string const &path, WIN32_FIND_DATA const &file) {
std::cout << path << file.cFileName << "\n";
}
void find_file(std::string const &folder_name, std::string const &fmask) {
HANDLE finder; // for FindFirstFile
WIN32_FIND_DATA file; // data about current file.
std::priority_queue<std::string, std::vector<std::string>,
std::greater<std::string> > dirs;
dirs.push(folder_name); // start with passed directory
do {
std::string path = dirs.top();// retrieve directory to search
dirs.pop();
if (path[path.size()-1] != '\\') // normalize the name.
path += "\\";
std::string mask = path + fmask; // create mask for searching
// traverse a directory. Search for sub-dirs separately, because we
// don't want a mask to apply to directory names. "*.cpp" should find
// "a\b.cpp", even though "a" doesn't match "*.cpp".
//
// First search for files:
if (HNULL==(finder=FindFirstFile(mask.c_str(), &file)))
continue;
do {
if (!(file.dwFileAttributes & A_DIR))
process(path, file);
} while (FindNextFile(finder, &file));
FindClose(finder);
// Then search for subdirectories:
if (HNULL==(finder=FindFirstFile((path + "*").c_str(), &file)))
continue;
do {
if ((file.dwFileAttributes & A_DIR) && (file.cFileName[0] != '.'))
dirs.push(path + file.cFileName);
} while (FindNextFile(finder, &file));
FindClose(finder);
} while (!dirs.empty());
}
int main(int argc, char **argv) {
if (argc > 2)
find_file(argv[1], argv[2]);
else
find_file("C:\\", "*");
return 0;
}
Why not use the boost recursive_directory_iterator . 为什么不使用boost recursive_directory_iterator呢 ?
Note: untested (but should look something like this). 注意:未经测试(但应该看起来像这样)。
namespace bfs = boost::filesystem;
std::vector<std::string> filenames;
std::copy(bfs::recursive_directory_iterator("<path>"),
bfs::recursive_directory_iterator(),
std::back_inserter(filenames)
);
I'd have a look at the directory iterators of boost instead. 我来看看boost的目录迭代器。
http://www.boost.org/doc/libs/1_51_0/libs/filesystem/doc/index.htm http://www.boost.org/doc/libs/1_51_0/libs/filesystem/doc/index.htm
There are examples covering what you are trying to do, and it will work for almost any OS you can think of. 有一些示例涵盖了您要尝试执行的操作,并且几乎可以在您能想到的任何操作系统上使用。
Have a look at example 3. It shows how to loop over all contents of the directory. 请看示例3。它显示了如何遍历目录的所有内容。 If you find a new directory you have not seen before, you just do the same on that. 如果找到一个以前从未见过的新目录,则只需对它进行同样的操作。 There are tests telling you if the file is regular, directory etc so give it a try. 有测试可以告诉您该文件是否是常规文件,目录等,因此请尝试一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.