【问题标题】:Check for writing permissions to file in Windows/Linux在 Windows/Linux 中检查文件的写入权限
【发布时间】:2011-04-17 11:26:18
【问题描述】:

我想知道如何检查我是否对文件夹有写权限。

我正在编写一个 C++ 项目,我应该将一些数据打印到一个 result.txt 文件中,但我需要知道我是否有权限。

Linux 和 Windows 之间的检查是否不同?因为我的项目应该在 Linux 上运行,而目前我在 Visual Studio 中工作。

【问题讨论】:

    标签: c++ file permissions


    【解决方案1】:

    唯一合理的做法是尝试创建文件,如果失败,告诉用户有问题。任何提前测试的尝试,并且只有在您能够创建和写入文件的情况下才尝试创建文件,否则会因竞争条件而出现问题(在您检查时已获得许可,但在您尝试时已将其删除使用它,反之亦然)和极端情况(例如,您有权限在该目录中创建文件,但尝试在那里写入将超出您的磁盘配额)。唯一知道的方法就是尝试...

    【讨论】:

      【解决方案2】:

      实际测试文件写入权限的最正确方法是尝试写入文件。这样做的原因是因为不同的平台以非常不同的方式公开写权限。更糟糕的是,仅仅因为操作系统告诉您可以(或不能)写入文件,它实际上可能是在撒谎,例如,在 unix 系统上,文件模式可能允许写入,但文件处于只读状态媒体,或者相反,该文件实际上可能是内核为进程自己使用而创建的字符设备,因此即使其文件模式设置为全零,内核也允许该进程(并且仅该进程)使用它它喜欢的一切。

      【讨论】:

        【解决方案3】:

        检查权限的可移植方法是尝试打开文件并检查是否成功。如果没有,并且errno(从标头<cerrno> 设置为值EACCES [是,有一个S],那么您没有足够的权限。这应该适用于Unix/LinuxWindows . stdio 示例:

        FILE *fp = fopen("results.txt", "w");
        if (fp == NULL) {
            if (errno == EACCES)
                cerr << "Permission denied" << endl;
            else
                cerr << "Something went wrong: " << strerror(errno) << endl;
        }
        

        Iostreams 的工作方式会有所不同。 AFAIK,他们不保证在两个平台上都设置errno,或者报告比“失败”更具体的错误。

        正如 Jerry Coffin 所写,不要依赖单独的访问测试函数,因为您的程序很容易出现竞争条件和安全漏洞。

        【讨论】:

        • 谢谢,但我仍然不明白如何知道我是否有权将文件写入磁盘。
        • 如果我尝试并且没有权限,我认为程序会崩溃,我想通过之前的检查来防止它。是否有任何命令可以检查磁盘写入权限(写入新文件)?
        • 为什么你的程序会崩溃? :S
        • 实际上这在 Windows 上不是一个好方法(至少不是,当你想检查时,如果你有更新应用程序的权限):运行的可执行文件始终是只读的,即使你有写权限(如果已结束);如果您尝试写入该文件,Windows 可能会在可写目录中创建该文件的虚拟副本,即使您没有写入权限
        • 我建议使用“a”模式。假设你有写权限并且你使用“fclose”;那么现有文件将被一个空文件覆盖...
        【解决方案4】:

        与接受的答案类似,但使用未弃用的 fopen_s 函数以及现代 C++ 和 append 打开模式以避免破坏文件内容:

        bool is_file_writable(const std::filesystem::path &file_path)
        {
            FILE* file_handle;
            errno_t file_open_error;
            if ((file_open_error = fopen_s(&file_handle, file_path.string().c_str(), "a")) != 0)
            {
                return false;
            }
        
            fclose(file_handle);
            return true;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-10
          • 2010-12-24
          • 2010-11-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-23
          相关资源
          最近更新 更多