C++ でファイルが存在するかどうかを確認する方法

この記事では、ディレクトリ内に特定のファイルが存在するかどうかを確認するための C++ メソッドを紹介します。ただし、以下のチュートリアルは C++ 17 の filesystem ライブラリをベースにしているので、新しいコンパイラでのみサポートされています。

ディレクトリにファイルが存在するかどうかを調べるには std::filesystem::exists を使う

exists メソッドはパスを引数に取り、既存のファイルやディレクトリに対応する場合は真偽値 true を返す。以下の例では、任意のファイル名を含むベクトルを初期化して exists 関数でファイルシステム内のファイル名を調べる。なお、exists メソッドは実行ファイルのあるカレントディレクトリのみをチェックすることに注意してください。

#include <iostream>
#include <vector>
#include <string>
#include <filesystem>

using std::cout; using std::cin;
using std::endl; using std::vector;
using std::filesystem::exists;
using std::string;

int main() {
    vector<string> files_to_check = {"main.cpp",
                                     "Makefile",
                                     "hello-world"};

    for (const auto &file : files_to_check) {
        exists(file) ? cout << "Exists\n" : cout << "Doesn't exist\n";
    }

    return EXIT_SUCCESS;
}

上記のコードは、for_Each STL アルゴリズムを用いて再実装することができ、コードの再利用性が向上します。

#include <iostream>
#include <vector>
#include <string>
#include <filesystem>

using std::cout; using std::cin;
using std::endl; using std::vector;
using std::filesystem::exists;
using std::string;

int main() {
    vector<string> files_to_check = {"main.cpp",
                                     "Makefile",
                                     "hello-world"};

    auto check = [](const auto &file)
            {exists(file) ? cout << "Exists\n" : cout << "Doesn't exist\n";};

    for_each(files_to_check.begin(), files_to_check.end(), check);

    return EXIT_SUCCESS;
}

この exists メソッドは、他の <filesystem> ライブラリルーチンと組み合わせることで、より有益な情報を得ることができます。is_directoryis_regular_file のような <filesystem> ライブラリルーチンと組み合わせれば、より有益な情報を得ることができます。一般的に、ファイルシステムのメソッドの中にはファイルとディレクトリを区別しないものもありますが、以下のサンプルコードに示すように、特定のファイル型チェック関数を使ってパス名を確認することができます。

#include <iostream>
#include <vector>
#include <string>
#include <filesystem>

using std::cout; using std::cin;
using std::endl; using std::vector;
using std::filesystem::exists;
using std::filesystem::is_directory;
using std::filesystem::is_regular_file;
using std::string;

int main() {
    vector<string> files_to_check = {"main.cpp",
                                     "Makefile",
                                     "hello-world"};

    for (const auto &file : files_to_check) {
        if (exists(file)){
           if (is_directory(file)) cout << "Directory exists\n";
           if (is_regular_file(file)) cout << "File exists\n";
           else cout << "Exists\n";
        } else {
            cout << "Doesn't exist\n";
        };
    };

    return EXIT_SUCCESS;
}

ここで、特定のディレクトリに移動して、特定のファイル名が存在するかどうかをチェックしたい場合を考えてみましょう。このためには、current_path メソッドを利用する必要があります。これは引数を渡さなければカレントディレクトリを返し、引数を与えればカレントディレクトリを指定したパスに変更することができます。プログラムの出力をよりよく確認するために、システムに応じてディレクトリのパスやファイル名を変更することを忘れないようにしてください。

#include <iostream>
#include <vector>
#include <string>
#include <filesystem>

using std::cout; using std::cin;
using std::endl; using std::vector;
using std::filesystem::exists;
using std::filesystem::is_directory;
using std::filesystem::is_regular_file;
using std::filesystem::current_path;
using std::string;

int main() {
    vector<string> files_to_check = {"main.cpp",
                                   "Makefile",
                                   "hello-world"};
    current_path("../");
    for (const auto &file : files_to_check) {
        exists(file) ? cout << "Exists\n" : cout << "Doesn't exist\n";
    }

    return EXIT_SUCCESS;
}

また、directory_iterator を繰り返し実行している間に、現在のユーザがディレクトリ内のファイルに対してどのようなパーミッションを持っているかを確認することもできます。status メソッドはパーミッションを取得し、perms という特別なクラスに格納するために使われます。取得したパーミッションは perms 構造体に対してビット単位の操作で表示することができます。以下の例では、所有者のパーミッションのみを抽出しています(一覧はこちら)。

#include <iostream>
#include <vector>
#include <string>
#include <filesystem>

using std::cout; using std::cin;
using std::endl; using std::vector;
using std::filesystem::exists;
using std::filesystem::directory_iterator;
using std::filesystem::perms;

using std::string;

int main() {
    vector<std::filesystem::perms > f_perm;
    string path = "../";

    for (const auto & file : directory_iterator(path)){
        cout << file << " - ";
        cout << ((file.status().permissions() & perms::owner_read) != perms::  none ? "r" : "-")
             << ((file.status().permissions() & perms::owner_write) != perms::  none ? "w" : "-")
             << ((file.status().permissions() & perms::owner_exec) != perms::  none ? "x" : "-")
             << endl;
    }
    cout << endl;
    return EXIT_SUCCESS;
}

関連記事 - C++ File

  • C++ でディレクトリ内のファイルの一覧を取得する方法
  • comments powered by Disqus