【问题标题】:std::filesystem::remove_all fails on read-only filestd::filesystem::remove_all 在只读文件上失败
【发布时间】:2022-01-20 21:07:30
【问题描述】:

我正在尝试使用 std::filesystem::remove_all() 从我的磁盘中删除完整的 git 存储库克隆

std::filesystem::remove_all( myRepoName );

这会引发异常

terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
  what():  filesystem error: cannot remove all: Input/output error [windex] 
[windex\.git\objects\pack\pack-6592b2cba8201deb33301b149bcb61af6b4be49b.idx]

这个文件是只读的。它可以从 Windows 资源管理器中毫无问题地删除。

这在 Windows 10 和 mingw g++ v11.2 中。所以这似乎是 std::filesystem 实现中的一个错误。

有什么可用的解决方法吗?也许std::filesystem::permissionshttps://en.cppreference.com/w/cpp/filesystem/permissions

尝试添加

    std::filesystem::permissions(
        "windex/.git/objects/pack/pack-3b1477e94a042244b9aed7021724d8a020be62c9.idx",
        std::filesystem::perms::others_all );

但仍然出现相同的错误并且文件仍然是只读的。

经过实验,发现owner_write可以做到这一点

【问题讨论】:

  • 我不得不问一个愚蠢的问题:您是否有任何进程可能打开了其中的任何文件?位于该文件夹中的资源管理器窗口? Windows 在这方面真的很受欢迎。
  • 你能捕捉到异常并打印出GetLastError返回的值吗?这可能会告诉你根本问题是什么。
  • 我的猜测是防病毒或锁定文件的 git 客户端。使用进程资源管理器可能会看到它打开了什么?
  • 这台电脑 -> 右键 -> 管理 -> 共享文件夹 -> 打开文件可能会告诉你一些事情。
  • 也许文件设置了只读属性?至少在我的系统上,".git/object/pack" 子文件夹中的所有文件都是只读的。您可以通过命令行检查:ATTRIB "windex\.git\objects\pack\pack-6592b2cba8201deb33301b149bcb61af6b4be49b.idx" 并查看是否存在 R 属性。 Microsoft C++ 标准库有一个 bug #1511,据说它仅在 VS 2022 17.0 Preview 3 之后才修复。

标签: c++ windows c++17 git-for-windows std-filesystem


【解决方案1】:

此代码通过更改任何无法删除的文件的只读权限来解决问题。

int count = 0;
while (count < 5)   //give up after 5, there should be just 2 in a git repo
{       
    try
    {
        std::filesystem::remove_all(myRepoName);
        break;     // all done
    }
    catch (std::filesystem::filesystem_error &e)
    {
        std::this_thread::sleep_for (std::chrono::milliseconds(250));
        std::string f ( e.what() );
        int p = f.find("[");
        p = f.find("[",p+1);
        f = f.substr(p+1);
        f = f.substr(0,f.length()-1);
        std::filesystem::permissions(
            f, std::filesystem::perms::owner_write );
        count++;
    }
}

【讨论】:

  • 很高兴知道您找到了快速解决方法。但是为什么你会发现一些奇怪的std::filesystem::__cxx11::filesystem_error 而不是标准的std::filesystem::filesystem_error 异常?您使用的是文件系统库的实验版本吗?或者这个__cxx11 部分只是一个内部实现细节?如果你改为捕获std::filesystem::filesystem_error 会发生什么?
  • 另外,如果一个文件夹中有超过 5 个只读文件会怎样? ;-P
  • @heapunderrun 我正在捕捉 __cxx11::filesystem_error 因为这是被抛出的异常。请参阅我的问题的第 4 段。
  • 一个 git repo 中有 2 个只读文件
  • std::filesystem::filesystem_error 有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
相关资源
最近更新 更多