掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
最下層にあるフォルダのパスを取得するには? (ID:50729)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
とにかくCFindFileクラスで再帰,というのが手段になるでしょうね。 5000 - 10000程度,今のマシンならメモリに蓄えても問題ないです。 私の趣味に走ると,次のような感じになります。 効率よりも書き易さ重視です(どこがだ)。 決して真似しないでください。見たことがないC++の構文がたくさん出てきているでしょうけど……。 #一応,ANSI/UNICODE両対応です。独自アロケータだろうが問題なく動きます。 template <typename T> struct traits; template <> struct traits<char> { typedef WIN32_FIND_DATAA win32_find_data; static const char * const dot_file; static const char * const double_dot_file; static const char asterisk; static const char reverse_solidus; }; template <> struct traits<wchar_t> { typedef WIN32_FIND_DATAW win32_find_data; static const wchar_t * const dot_file; static const wchar_t * const double_dot_file; static const wchar_t asterisk; static const wchar_t reverse_solidus; }; const char * const traits<char>::dot_file = "."; const char * const traits<char>::double_dot_file = ".."; const char traits<char>::asterisk = '*'; const char traits<char>::reverse_solidus = '\\'; const wchar_t * const traits<wchar_t>::dot_file = "."; const wchar_t * const traits<wchar_t>::double_dot_file = ".."; const wchar_t traits<wchar_t>::full_stop = '.'; const wchar_t traits<wchar_t>::asterisk = L'*'; const wchar_t traits<wchar_t>::reverse_solidus = L'\\'; inline HANDLE findFirstFile (const char * file, WIN32_FIND_DATAA & wfd) { return ::FindFirstFileA(file, &wfd); } inline HANDLE findFirstFile (const wchar_t * file, WIN32_FIND_DATAW & wfd) { return ::FindFirstFileW(file, &wfd); } inline bool findNextFile (HANDLE hFind, WIN32_FIND_DATAA & wfd) { return ::FindNextFileA(hFind, &wfd) != FALSE; } inline bool findNextFile (HANDLE hFind, WIN32_FIND_DATAW & wfd) { return ::FindNextFileW(hFind, &wfd) != FALSE; } inline bool findClose (HANDLE hFind) { return ::FindClose(hFind) != FALSE; } template <typename T, class CT, class AT, class AV> bool findFiles (const std::basic_string<T, CT, AT> & base, std::vector<std::basic_string<T, CT, AT>, AV> & result) { typedef traits<T> traits_type; typedef traits_type::win32_find_data wfd_type; typedef std::basic_string<T, CT, AT> string_type; wfd_type wfd; HANDLE hFind; bool ret = false; hFind = findFirstFile(string_type(base).append(1, traits_type::asterisk).c_str(), wfd); if (hFind == INVALID_HANDLE_VALUE) return false; do { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) continue; if (CT::compare(wfd.cFileName, traits_type::dot_file, 2) == 0 || CT::compare(wfd.cFileName, traits_type::double_dot_file, 3) == 0) continue; if (!findFiles((base + wfd.cFileName).append(1, traits_type::reverse_solidus), result)) { result.push_back(base + wfd.cFileName); } ret = true; } while (findNextFile(hFind, wfd)); findClose(hFind); return ret; } ちなみに,findFilesをcharについて展開すると,次のようになります。 bool findFiles (const std::string & base, std::vector<std::string> & result) { WIN32_FIND_DATAA wfd; // WIN32_FIND_DATAA : WIN32_FIND_DATA for ANSI HANDLE hFind; bool ret = false; hFind = FindFirstFileA((base + "*").c_str(), &wfd); // FindFirstFileA : FindFirstFile for ANSI if (hFind == INVALID_HANDLE_VALUE) return false; do { if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) continue; if (std::strcmp(wfd.cFileName, ".") == 0 || std::stdcmp(wfd.cFileName, "..") == 0) continue; if (!findFiles(base + wfd.cFileName + "\\", result)) { result.push_back(base + wfd.cFileName); } ret = true; } while (FindNextFileA(hFind, &wfd)); // FindNextFileA : FindNextFile for ANSI FindClose(hFind); return ret; } こっちならわかりよいかと。たぶん,再帰を潰してもそれほど効果はないでしょう。
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.