如何在 C++ 中檢查一個檔案是否存在
Jinku Hu
2023年10月12日
本文將介紹在 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_directory
和 is_regular_file
。一般來說,一些檔案系統方法不區分檔案和目錄,但我們可以使用特定的檔案型別檢查函式來驗證路徑名,如下面的示例程式碼所示。
#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;
}
作者: Jinku Hu