LoginSignup
17
18

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-01-13

1 はじめに

大量の画像をOpenCVで画像処理するときに、フォルダ以下にあるファイル一覧を取得したかったので、その関数を作成しました。
(2019/1/18 追記)
コメントで教えて頂いたfilesystemを使う方法も追記しました。

2 WinAPIを使う

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

2.1 ソースコード

FileNames.cpp
/**
* @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 出力結果

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

3 filesystemを使う

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

3.1 ソースコード

FileNames.cpp
/**
* @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配列にフォルダ以下にあるファイルの絶対パスが格納されます。サブフォルダは格納されません。
result.png

4 参考サイト

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

17
18
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
18