最可靠的方式是用std::filesystem::status()获取文件权限位,但需调用permissions()并按位判断owner_write等标志,且注意Windows的FILE_ATTRIBUTE_READONLY与POSIX权限语义不同。

用 std::filesystem::status() 检查文件权限位
在 C++17 及以上,std::filesystem 是最直接、跨平台的方式。它通过 status() 获取文件状态,再用 perms 枚举判断只读性——注意:这里“只读”指**当前用户无写权限**,而非 Windows 的“只读属性位”(二者语义不同,后文会说明)。
实操建议:
立即学习“C++免费学习笔记(深入)”;
-
status()返回file_status,调用.permissions()得到perms值 - 检查是否包含
owner_write、group_write、others_write任一权限位;若全无,可认为对当前用户只读 - 需捕获
std::filesystem::filesystem_error,例如路径不存在或无访问权限时会抛异常
#include <filesystem>
#include <iostream>
bool is_readonly(const std::string& path) {
try {
auto p = std::filesystem::status(path).permissions();
return !(p & std::filesystem::perms::owner_write) &&
!(p & std::filesystem::perms::group_write) &&
!(p & std::filesystem::perms::others_write);
} catch (const std::filesystem::filesystem_error&) {
return false; // 无法获取状态,默认不视为只读(或按需处理)
}
}
Windows 下读取 FILE_ATTRIBUTE_READONLY 属性
Windows 文件系统有独立的“只读属性”(attribute),和 Unix 权限分离。它不影响实际写入能力(比如管理员仍可写),但被许多 GUI 工具和部分 API(如 CreateFile)识别。若业务逻辑依赖这个标记(如资源管理器显示小锁图标),必须单独检查。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
GetFileAttributesA()或GetFileAttributesW()获取属性值 - 检查返回值是否包含
FILE_ATTRIBUTE_READONLY标志位 - 注意:该函数对目录也返回有效值,且路径末尾不能是反斜杠(否则可能返回
INVALID_FILE_ATTRIBUTES)
#ifdef _WIN32
#include <windows.h>
bool has_win_readonly_attr(const std::string& path) {
DWORD attr = GetFileAttributesA(path.c_str());
return (attr != INVALID_FILE_ATTRIBUTES) &&
(attr & FILE_ATTRIBUTE_READONLY);
}
#endif
为什么 stat() 在 Linux/macOS 上不适用“只读属性”概念
Linux 和 macOS 没有 Windows 那种独立的只读属性位。它们完全依赖 POSIX 权限位(st_mode 中的 S_IWUSR 等)。因此调用 stat() 后检查 st_mode & S_IWUSR 等,本质和 std::filesystem::status() 底层行为一致。
常见错误现象:
- 误以为
stat()能返回类似 Windows 的“只读属性”,结果在 Linux 上永远得不到预期值 - 混淆“当前用户能否写”和“文件是否被标记为只读”——前者是权限问题,后者是元数据标记,仅 Windows 存在后者
- 未考虑 umask 或 ACL,导致仅靠
st_mode判断不准确(std::filesystem内部已考虑 effective permissions)
跨平台判断只读的实用策略
没有一刀切的方案。你需要先明确“只读”在你场景中代表什么:
- 如果目标是阻止用户意外修改(如配置文件保护),应优先用
std::filesystem::status()——它反映真实写入能力 - 如果目标是兼容 Windows 资源管理器行为或旧工具链(如某些打包脚本依赖
attrib +R),则必须额外调用 Windows API 检查FILE_ATTRIBUTE_READONLY - 不要混合使用:比如在 Windows 上只检查属性位而忽略权限,会导致管理员用户仍能写入却误判为“安全”
复杂点在于,同一个文件在 Windows 上可能同时具备 FILE_ATTRIBUTE_READONLY 和 owner_write 权限——此时用户能写,但 Explorer 显示只读图标。这种歧义必须由业务逻辑显式决策,库本身不会替你 resolve。


















