0

すべてのディレクトリ内のすべてのファイルを検索しようとしていますが、サブディレクトリの処理方法がわかりません。このコードでは、コードはすべてのサブディレクトリを通過しているように見えますが、戻る方法がわかりません。誰もこれを行う方法を知っていますか?

__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:関数はコンパイラを混乱させる同じ名前を持っていました

4

5 に答える 5

1

それを行う最も簡単な方法は、再帰関数を実行することだと思います。

これは、「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 );
       }
   }
}
于 2012-09-24T16:25:00.680 に答える
1

ブーストrecursive_directory_iteratorを使用しない理由。

注: 未テスト (ただし、次のように見えるはずです)。

namespace bfs = boost::filesystem;

std::vector<std::string>    filenames;

std::copy(bfs::recursive_directory_iterator("<path>"),
          bfs::recursive_directory_iterator(),
          std::back_inserter(filenames)
         );
于 2012-09-24T18:03:24.357 に答える
0

代わりに、boost のディレクトリ イテレータを見てみましょう。

http://www.boost.org/doc/libs/1_51_0/libs/filesystem/doc/index.htm

あなたがやろうとしていることをカバーする例があり、あなたが考えることができるほとんどすべてのOSで機能します.

例 3 を見てください。ディレクトリのすべての内容をループする方法を示しています。以前に見たことのない新しいディレクトリを見つけた場合は、それに対して同じことを行うだけです。ファイルが通常かどうか、ディレクトリなどかどうかを示すテストがありますので、試してみてください。

于 2012-09-24T16:16:12.207 に答える
0

を介してディレクトリを変更する代わりにSetCurrentDirectory()、 で再帰呼び出しを使用しGetFiles()ます。std::vector<std::string>これには、ローカル配列を使用する代わりに、ファイルのリストを格納するために、呼び出し元が配列 (または) への参照を渡す必要がありますs

于 2012-09-24T16:18:02.823 に答える
0

古い投稿を少し検索すると、幅優先検索を行うことについて何度も言及したと思いますが、その方法を示すコードを実際に投稿したことはありません。私はそれをしてもいいと思います。

#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;
}
于 2012-09-24T17:31:10.957 に答える