文件系统不支持“只写”权限,windows和posix均无对应权限位;所谓“只写”实为目录权限限制、acl细粒度控制或文件句柄占用导致的错觉;检测写权限应直接尝试open/createfile而非解析stat或属性。

只写权限在文件系统中并不存在
Windows 和 POSIX(Linux/macOS)文件系统都不支持“只写”这种孤立权限。所谓“只写”,意味着能写入但不能读取——这在底层文件系统设计上不可行:写操作(如 open(..., O_WRONLY) 或 CreateFile)本身可能触发元数据检查、空间校验或缓存预分配,这些都需要至少最低限度的元数据访问权限;更关键的是,所有主流系统要求对文件执行写操作前,进程必须拥有对该路径的**执行(x)权限(目录)和/或写(w)权限(文件)**,但**从不单独定义“仅可写、不可读”的权限位**。
实际中你遇到的“看似只写”现象是怎么来的
常见于以下场景,本质是权限组合或访问控制策略导致的错觉:
-
目录级限制:用户对某目录有
w权限但无r权限,可创建/覆盖该目录下的文件(如open("dir/file.txt", O_WRONLY | O_CREAT)成功),但无法ls dir或open("dir/file.txt", O_RDONLY)—— 这不是文件本身“只写”,而是目录遍历被拒 -
ACL 或 Windows DACL 细粒度控制:例如 Windows 上某文件 ACL 显式授予
FILE_WRITE_DATA但拒绝FILE_READ_DATA。此时CreateFile带GENERIC_WRITE可成功,但GENERIC_READ会返回ERROR_ACCESS_DENIED -
文件已打开且句柄未关闭:一个进程以
O_WRONLY打开后未关闭,另一进程尝试O_RDONLY会失败(取决于O_EXCL和锁机制),但这与权限无关,是同步问题
如何用 C++ 实际检测“能否写入该文件”
不要试图查“是否只写”,而应直接测试目标操作是否可行。跨平台可靠做法是模拟你要做的写行为:
- POSIX 系统:调用
access(path.c_str(), W_OK)检查写权限(注意:它不保证后续open()一定成功,但能快速排除多数无权情况) - Windows:用
GetFileAttributes检查FILE_ATTRIBUTE_READONLY位(仅对应只读属性,非权限);真正权限需用AccessCheck+GetNamedSecurityInfo获取 DACL 并评估,但开销大,通常直接尝试CreateFile(..., GENERIC_WRITE, ...)更实用 - 统一建议:直接
open(path.c_str(), O_WRONLY | O_NONBLOCK)(POSIX)或CreateFile(path.c_str(), GENERIC_WRITE, ..., OPEN_EXISTING)(Windows),检查返回值和errno/GetLastError()。失败时若错误码为EACCES或ERROR_ACCESS_DENIED,即表明当前进程无写权限
为什么不能靠 stat() / GetFileInformationByHandle 判断“只写”
stat() 返回的 st_mode 中的 S_IWUSR 等位,只表示“用户有写权限”,它从不隐含“无读权限”。同样,Windows 的 GetFileInformationByHandle 返回的 dwFileAttributes 里只有 FILE_ATTRIBUTE_READONLY,没有“WRITE_ONLY”标志。试图从这些 API 中解析出“只写”结论,逻辑上不成立,代码必然误判。
真正的权限决策发生在系统调用入口(open/CreateFile),由 VFS 层或对象管理器实时校验 ACL/DACL。任何提前读取静态属性的做法,都无法替代一次真实的、带目标访问模式的打开尝试。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











