【问题标题】:How does one test if a file is LOCKED and/or read-only without opening?如何测试文件是否被锁定和/或只读而不打开?
【发布时间】:2019-05-28 17:47:02
【问题描述】:

是否有一种可移植的 (std::filesystem) 方法来测试文件是“锁定”还是具有“只读”权限?例如,MacOS Finder 有一个“锁定”设置,它不同于标准 POSIX 的“权限”。

在尝试执行删除操作之前,我需要测试是否可以删除文件。理想情况下,我想避免打开文件以进行 R/W 作为测试。

这是在 SAVE/RENAME 过程中,并且(至少在过去的 MacOS 文件系统中),即使文件在 Finder 中被“锁定”,操作系统调用“交换”两个文件仍然有效。由于文件如何保存以及如何“保留”以前的版本的复杂性,最好提前知道这样可以避免操作。

进一步说明:在具有读写权限的 LOCKED 文件上以 R/W (std::ios::out | std::ios::in) 的形式打开流将失败,并且 errno = 1(不允许操作) .如果文件为只读但未锁定,则会失败并显示 errno 13(权限被拒绝)。

此处讨论了测试锁定位的 MacOS (Cocoa) 特定方法:

How to check whether a file is locked in Cocoa?

【问题讨论】:

  • 出于好奇,您为什么要避免使用该解决方案?这似乎是规范的做法。获取句柄,如果有效,则取消链接路径,然后关闭句柄。这就是避免竞争条件的方法。但是我不认为可写性 == 可删除性,所以这也不是万无一失的......
  • 即使有这样的测试,也只会导致上述 cmets 正确说明的竞态条件。删除文件,如果失败,记录警告,这是正确的过程。无论如何,删除操作都很便宜。
  • 我认为你需要在你的问题中解释为什么只调用 std::remove 并检查失败是不够的,特别是考虑到其他人已经评论过关于测试的竞争条件以查看是否文件被锁定。
  • 如果某事物与仅存在于某些操作系统上且不属于“标准 POSIX”的一部分的概念相关,那么它怎么可能是“可移植的”?这里的“便携”是什么意思?
  • "如何测试文件是否被锁定和/或只读而不打开?" - 这完全是操作系统(和文件系统)特定的。据我所知,没有跨平台/便携的方法可以做到这一点。你只需要编写代码来检查你支持的每个平台,无论平台要求你做什么。

标签: c++ posix c++17 boost-filesystem std-filesystem


【解决方案1】:

好的——这可能不是准确的答案,但看起来你可以这样做(如建议here

#include <sys/stat.h>

bool IsLocked(std::string& thePath)
{
    bool isLocked = false;

    struct stat buf;
    int retval = stat(thePath.c_str(), &buf);     // NOTE: retval could be an error, like ENOENT (file doesn't exist)
    if (0 != (buf.st_flags & UF_IMMUTABLE)) {
        isLocked = true;
         //is immutable
    }

    return isLocked;
}

在我自己的代码中,我以更健壮的方式处理 retval 错误。你也应该!

但请注意:虽然这可以正确指示文件的 Finder 锁定位/标志的状态,但它不能反映文件是否为“只读”。 UF_IMMUTABLE 上的文档说“文件可能不会被更改”——这显然是不准确的。

【讨论】:

    猜你喜欢
    • 2014-01-13
    • 2011-02-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 2010-12-26
    • 2015-06-06
    • 1970-01-01
    相关资源
    最近更新 更多