HOWTO · C++
如何在 C++ 中检查一个文件是否存在
本文介绍了检查目录下文件是否存在的几种方法,C++
本页内容
使用 std::filesystem::exists 检查路径是否指向现有的文件系统条目。对于文件和目录,该函数都会返回 true。下面的示例会创建一个小型临时目录和文件,作为可独立运行的检查对象;请将 file 替换为程序需要检查的路径。
使用 std::filesystem::exists 检查目录中的文件是否存在
运行以下示例:
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
int main() {
namespace fs = std::filesystem;
const auto unique = std::chrono::steady_clock::now().time_since_epoch().count();
const fs::path folder = fs::temp_directory_path() /
("cpp-exists-" + std::to_string(unique));
std::error_code ec;
if (!fs::create_directory(folder, ec) || ec) {
std::cout << "Could not prepare example\n";
return 1;
}
struct cleanup_guard {
fs::path path;
~cleanup_guard() {
std::error_code cleanup_error;
fs::remove_all(path, cleanup_error);
}
} cleanup{folder};
const fs::path file = folder / "notes.txt";
{
std::ofstream output(file);
if (!output) {
std::cout << "Could not prepare example\n";
return 1;
}
}
std::cout << (fs::exists(file) ? "Path exists\n" : "Path does not exist\n");
std::cout << (fs::is_regular_file(file) ? "It is a regular file\n"
: "It is not a regular file\n");
}
Path exists
It is a regular file
调用 fs::exists(file) 会检查传入的路径,不会搜索同名文件。此处的 folder / "notes.txt" 使用 std::filesystem::path 将指定目录与文件名拼接起来,并自动处理平台对应的路径分隔符。如果目标不在进程的当前工作目录中,可以用相同方式与自己的目录路径拼接。
相对路径(例如 "notes.txt")是相对于进程的当前工作目录解析的;该目录由程序的启动环境决定。相对路径不会自动以可执行文件所在目录为基准。要查看当前工作目录,可以调用 fs::current_path();要更改进程的当前工作目录,可以使用 fs::current_path(path),并处理可能报告的文件系统错误。如果只需检查一个位置,直接用已知目录构造路径通常更清楚。
exists 回答的是某个条目是否存在,而不是它属于哪种类型。如果只接受普通文件,请使用 fs::is_regular_file(path);如果预期的是目录,请使用 fs::is_directory(path)。当程序没有访问文件系统的权限,或检查期间路径发生变化时,这些检查也可能无法给出可用结果。若代码需要区分这些情况,请使用接受 std::error_code 的重载,并将错误与返回的布尔值分开检查。
例如,std::error_code ec; const bool found = fs::exists(path, ec); 可以让调用者同时检查 found 和 ec:如果结果为 false 且没有错误,表示未找到该路径;如果设置了错误,则说明检查未能完成的原因。不带错误码参数的重载会在发生文件系统错误时抛出异常。如果代码需要在预期的文件系统问题发生时继续处理,请选择错误码形式;否则,抛出异常的形式能让简单检查保持简洁。路径也可能在检查之后、后续打开之前不再指向同一个条目,因此应把检查结果视为一次查找结果,而不是保证后续操作成功。
示例使用 std::filesystem,并自行创建临时测试目录和文件。如果目录或文件创建失败,程序会输出准备阶段的提示并以非零状态返回。清理保护机制会尝试在正常退出时删除临时目录,并忽略清理错误。查询使用会抛出异常的重载;如果文件系统异常未被捕获并从 main 中逸出,程序可能终止,此时不能保证保护对象的析构函数会运行。正常执行时,示例会输出上方所示的两行结果,其中的标签仍为英文。