0

0

C++ 怎么判断文件只读 C++ access函数检查写权限【权限】

穿越時空

穿越時空

发布时间:2026-01-28 14:57:09

|

412人浏览过

|

来源于php中文网

原创

access 不能可靠判断文件只读,因其仅检查真实UID/GID的写权限,易受NFS、目录权限、Windows属性等干扰;应改用stat结合UID/GID比对或直接open/CreateFile验证。

c++ 怎么判断文件只读 c++ access函数检查写权限【权限】

access 检查文件是否只读,为什么常返回错误结果

access 本身不直接判断“只读”,它只能检查当前进程是否有某类权限(如写权限)。所谓“只读”,其实是通过 access(path, W_OK) 返回 -1 来**间接推断**:如果写权限被拒绝,且文件存在、可读,那它大概率是只读的。但要注意:access 检查的是**真实用户 ID 和组 ID 的权限**,不是有效 ID,所以在 setuid 程序中可能和实际 open 行为不一致。

常见误判场景包括:

  • 文件在 NFS 或某些虚拟文件系统上,access 可能始终返回 -1(即使实际可写)
  • 目录有写权限,但文件本身被 chmod 444,access("file", W_OK) 仍可能返回 0(因为目录可写,允许 unlink)——这不代表你能修改文件内容
  • Windows 下 access 对只读属性的判断依赖文件系统属性位,而非 POSIX 权限,和 Linux 行为不一致

stat + st_mode 才能可靠判断只读属性(跨平台需注意)

真正判断一个普通文件是否“只读”,应结合 stat 获取 st_mode,再检查用户/组/其他三类权限位中是否有写位(S_IWUSRS_IWGRPS_IWOTH),并确认它不是目录(否则写权限意义不同)。

示例逻辑:

立即学习C++免费学习笔记(深入)”;

#include 
bool is_file_readonly(const char* path) {
    struct stat sb;
    if (stat(path, &sb) != 0) return false; // 文件不存在或无访问权
    if ((sb.st_mode & S_IFMT) != S_IFREG) return false; // 非普通文件
    uid_t uid = getuid();
    gid_t gid = getgid();
    bool user_can_write = (sb.st_mode & S_IWUSR) && (sb.st_uid == uid);
    bool group_can_write = (sb.st_mode & S_IWGRP) && (sb.st_gid == gid);
    bool other_can_write = (sb.st_mode & S_IWOTH);
    return !(user_can_write || group_can_write || other_can_write);
}

注意:getuid()getgid() 是必须的,仅看 mode 位而不比对 UID/GID 会误判(比如你不是文件属主,但其他用户有写权,你依然不能写)。

Windows 下要用 GetFileAttributes 替代 access

Windows 没有 POSIX 权限模型,文件“只读”由单独的只读属性位控制(FILE_ATTRIBUTE_READONLY),和 ACL 是两套机制。此时 access(path, W_OK) 在 MinGW 或 MSVC 中可能模拟得不准确,尤其对 NTFS ACL 复杂的路径。

Getimg.ai
Getimg.ai

getimg.ai是一套神奇的ai工具。生成大规模的原始图像

下载

更稳妥的做法:

  • GetFileAttributesAGetFileAttributesW
  • 检查返回值是否包含 FILE_ATTRIBUTE_DIRECTORY(跳过目录)
  • 再检查是否含 FILE_ATTRIBUTE_READONLY 且不含 FILE_ATTRIBUTE_HIDDENFILE_ATTRIBUTE_SYSTEM(这些属性不影响写,但常被误认为“只读”)

注意:该属性可被用户随时修改(右键 → 属性 → 勾选只读),但它不阻止管理员或拥有写 ACL 的用户修改文件 —— 所以它只是轻量提示,不是权限强制。

真正想“尝试写”,就别绕开 openfopen

所有静态检查(accessstatGetFileAttributes)都只是快照。文件权限可能在检查后瞬间被其他进程修改,或者受 mount 选项(如 ro)、SELinux/AppArmor 等策略拦截。

如果你的逻辑本质是“我要写这个文件,先确保能写”,最可靠的方式永远是直接尝试:

  • Linux/macOS:int fd = open(path, O_WRONLY | O_NONBLOCK);,检查 fd == -1 && errno == EACCES
  • Windows:HANDLE h = CreateFile(path, GENERIC_WRITE, ..., OPEN_EXISTING, ...);,检查 h == INVALID_HANDLE_VALUEGetLastError() == ERROR_ACCESS_DENIED

这种做法看似“暴力”,实则避免了竞态条件(TOCTOU),也是 glibc 和 CRT 内部的真实行为。很多开发者执着于提前判断,反而引入了本可避免的 bug。

权限判断的复杂点从来不在函数调用本身,而在于你究竟要解决什么问题:是给用户显示一个灰色按钮?还是防止程序崩溃?前者可以宽松估算,后者必须用实际打开来验证。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

443

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

544

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

73

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

761

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1128

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

800

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

454

2023.08.02

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

134

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.9万人学习

Git 教程
Git 教程

共21课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号