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

胡金庫 2023年10月12日
C++ でファイルが存在するかどうかを確認する方法

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

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

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

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

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

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 <filesystem>
#include <iostream>
#include <string>
#include <vector>

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

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 <filesystem>
#include <iostream>
#include <string>
#include <vector>

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

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 <filesystem>
#include <iostream>
#include <string>
#include <vector>

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

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 <filesystem>
#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::filesystem::directory_iterator;
using std::filesystem::exists;
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;
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ File