如何在 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