tech notes

センシング、画像処理、xR

C++でフォルダ以下のファイル一覧を取得する

1 はじめに

大量の画像をOpenCVで画像処理するときに、フォルダ以下にあるファイル一覧を取得したかったので、その関数を作成しました。
※こちらの記事はQiitaで投稿した記事を移行したものとなります

2 WinAPIを使う

参考サイト[1]を参照して作成しました。C++17以降が使用できる環境であれば、後述しているfilesystemを使う方法がおすすめです。

2.1 ソースコード

/**
* @brief フォルダ以下のファイル一覧を取得する関数
* @param[in]   folderPath  フォルダパス
* @param[out]  file_names  ファイル名一覧
* return       true:成功, false:失敗
**/
bool getFileNames(std::string folderPath, std::vector<std::string> &file_names)
{
    HANDLE hFind;
    WIN32_FIND_DATA win32fd;
    std::string search_name = folderPath + "\\*";

    hFind = FindFirstFile(search_name.c_str(), &win32fd);

    if (hFind == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("file not found");
        return false;
    }

    /* 指定のディレクトリ以下のファイル名をファイルがなくなるまで取得する */
    do {
        if (win32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            /* ディレクトリの場合は何もしない */
            printf("directory\n");
        }
        else {
            /* ファイルが見つかったらVector配列に保存する */
            file_names.push_back(win32fd.cFileName);
            printf("%s\n", file_names.back().c_str());
        }
    } while (FindNextFile(hFind, &win32fd));

    FindClose(hFind);

    return true;
}

2.2 出力結果

関数の実行結果は下図の通りです。

f:id:tes2840:20200507043701p:plain
2.2_関数実行結果

3 filesystemを使う

C++17で標準入りしたfilesystemを使う方法を書きました。こちらの方法では絶対パスが得られます。 Visual Studio 2017でC++17を使う方法は参考サイト[2]を参照してください。

3.1 ソースコード

/**
* @brief フォルダ以下のファイル一覧を取得する関数
* @param[in]   folderPath  フォルダパス
* @param[out]  file_names  ファイル名一覧
* return       true:成功, false:失敗
*/
bool getFileNames(std::string folderPath, std::vector<std::string> &file_names)
{
    using namespace std::filesystem;
    directory_iterator iter(folderPath), end;
    std::error_code err;

    for (; iter != end && !err; iter.increment(err)) {
        const directory_entry entry = *iter;

        file_names.push_back( entry.path().string() );
        printf("%s\n", file_names.back().c_str());
    }

    /* エラー処理 */
    if (err) {
        std::cout << err.value() << std::endl;
        std::cout << err.message() << std::endl;
        return false;
    }
    return true;
}

3.2 出力結果

vector配列にフォルダ以下にあるファイルの絶対パスが格納されます。サブフォルダは格納されません。

f:id:tes2840:20200507043741p:plain
3.2_出力結果

4 参考サイト

[1] http://d.hatena.ne.jp/s-kita/20100129/1264776052
[2] https://codezine.jp/article/detail/10890