如何在 C++ 中检查一个文件是否存在

Jinku Hu 2020年10月15日
如何在 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。一般来说,一些文件系统方法不区分文件和目录,但我们可以使用特定的文件类型检查函数来验证路径名,如下面的示例代码所示。

#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;
}
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C++ File