You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++17的std::filesystem模拟access函数检查文件读写权限

用C++17 std::filesystem模拟Unix access()的R_OK/W_OK检查

Unix的access()函数会结合进程身份、文件权限位、ACL等因素,检查进程实际能否访问文件;直接用std::filesystem::perms检查权限位无法覆盖所有场景,最准确的方式是实际尝试执行对应的访问操作,以下是具体实现:

模拟access(path, R_OK)(检查可读)

#include <filesystem>
#include <fstream>

namespace fs = std::filesystem;

bool is_readable(const fs::path& path) {
    if (!fs::exists(path)) {
        return false;
    }

    if (fs::is_directory(path)) {
        // 目录可读:尝试获取目录迭代器,验证能否遍历目录内容
        try {
            [[maybe_unused]] auto dir_it = fs::directory_iterator(path);
            return true;
        } catch (const fs::filesystem_error&) {
            return false;
        }
    } else {
        // 文件可读:尝试以只读模式打开
        std::ifstream file(path, std::ios::in);
        return file.is_open();
    }
}

模拟access(path, W_OK)(检查可写)

#include <filesystem>
#include <fstream>

namespace fs = std::filesystem;

bool is_writable(const fs::path& path) {
    if (!fs::exists(path)) {
        // 文件不存在时,检查父目录是否允许创建新文件
        fs::path parent_dir = path.parent_path().empty() ? fs::current_path() : path.parent_path();
        if (!fs::exists(parent_dir) || !fs::is_directory(parent_dir)) {
            return false;
        }

        try {
            fs::path temp_file = parent_dir / fs::unique_path();
            std::ofstream temp_out(temp_file);
            if (temp_out.is_open()) {
                temp_out.close();
                fs::remove(temp_file);
                return true;
            }
            return false;
        } catch (const fs::filesystem_error&) {
            return false;
        }
    } else {
        if (fs::is_directory(path)) {
            // 目录可写:尝试创建临时文件验证能否写入
            try {
                fs::path temp_file = path / fs::unique_path();
                std::ofstream temp_out(temp_file);
                if (temp_out.is_open()) {
                    temp_out.close();
                    fs::remove(temp_file);
                    return true;
                }
                return false;
            } catch (const fs::filesystem_error&) {
                return false;
            }
        } else {
            // 文件可写:以追加模式打开,避免截断原有内容
            std::ofstream file(path, std::ios::out | std::ios::app);
            return file.is_open();
        }
    }
}

关键说明

  1. 避免直接检查权限位:std::filesystem::perms仅返回文件的静态权限位,无法处理SUID/SGID、ACL、进程有效身份等场景,实际尝试访问是最符合access()逻辑的方式。
  2. 目录与文件区分处理:
    • 目录的读权限对应能否遍历内容,通过创建目录迭代器验证;
    • 目录的写权限对应能否创建/删除文件,通过临时文件创建验证。
  3. 无副作用设计:临时文件创建后立即删除,不会留下残留;文件写检查用追加模式,避免修改原有文件内容。
  4. 跨平台兼容:基于C++17标准库实现,同时支持Unix和Windows系统。

内容的提问来源于stack exchange,提问作者Fede2424

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 16:32:41