c++中没有std::filesystem::open_file函数;文件打开应使用std::fstream,异常需手动启用exceptions()掩码;std::filesystem操作仅在未提供error_code参数时才抛filesystem_error(继承自system_error);权限检查应主动探路而非依赖异常兜底。

std::filesystem::open_file 失败时拿不到 std::system_error?
不是 std::filesystem::open_file 拿不到,是它根本不存在——C++20 标准里压根没这个函数。常见误写源于把 Python 或其他语言习惯带进来了。真正该用的是 std::fstream 构造或 open() 成员函数,异常触发依赖于流的状态位和是否启用了异常掩码。
-
std::ifstream f("locked.txt");默认不抛异常,即使文件被系统锁定或权限不足,f.fail()为 true,但不会进入catch - 必须手动调用
f.exceptions(std::ios_base::failbit | std::ios_base::badbit);才能让打开失败转为std::ios_base::failure异常(注意:不是std::system_error) - 权限拒绝类错误(如 EACCES)在底层由 OS 返回,
std::fstream不会自动包装成std::system_error;只有std::filesystem操作(如std::filesystem::create_directories)才可能抛std::filesystem::filesystem_error,其基类才是std::system_error
捕获文件权限异常该 catch 哪个类型?
取决于你用的是哪套 API:C 风格、C++ 流、还是 std::filesystem。三者异常体系互不兼容,混用会导致漏捕获。
- 用
std::fstream+exceptions():捕获std::ios_base::failure,再通过e.code().value()查看原始 errno(如 13 表示 EACCES) - 用
std::filesystem::remove("read_only.txt"):直接抛std::filesystem::filesystem_error,可catch (const std::filesystem::filesystem_error& e),e.code().value()同样返回 13 - 手撸
open()系统调用(#include <fcntl.h></fcntl.h>):返回 -1,查errno,此时完全不走 C++ 异常机制,try-catch无效
为什么 try-catch 住 std::filesystem 操作却没进 catch?
因为默认不抛异常——std::filesystem 几乎所有函数都提供两个重载:一个带 std::error_code& 参数的无异常版本,一个不带、可能抛 std::filesystem::filesystem_error 的版本。但“可能抛”不等于“一定抛”,它只在出错且未提供 std::error_code 参数时才抛。
- 写成
std::filesystem::copy("src", "dst", ec);(带ec)→ 永远不抛异常,错误信息全在ec里 - 写成
std::filesystem::copy("src", "dst");(不带ec)→ 权限不足时才抛std::filesystem::filesystem_error - 常见坑:头文件漏了
#include <system_error></system_error>,导致编译器静默降级为无异常版本,或者catch(...)捕到异常但无法访问.code()
权限检查别等打开失败再做
靠异常兜底是被动防御,容易让程序卡在 IO 路径上。更稳的做法是在 open 前用 std::filesystem::status() 或 access() 主动探路。
-
std::filesystem::status(path).permissions()可读取 ACL 位,但不反映当前进程真实权限(比如 umask、SELinux 策略) - 跨平台稳妥法:用
access(path.c_str(), R_OK)(Linux/macOS)或GetFileAttributes()(Windows),它们模拟实际 open 行为 - 注意时序漏洞:检查通过后到真正 open 前,文件权限可能已被其他进程修改。所以检查 + open 仍需包裹 try-catch,只是把“未知失败”变成“已知风险”
catch 形同虚设。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











