Visual Studio 为什么std::filesystem::copy_file()会忽略create_hard_links选项标志?

xriantvc  于 2023-03-09  发布在  其他
关注(0)|答案(1)|浏览(83)

我正在写一个函数来复制大的二进制图像。我首先尝试通过硬链接来复制它们。如果失败了,那么我就退而求其次来正常复制它们。
我最初编写这个函数是为了使用std::filesystem::copy_file(),如下所示:

public bool CopyLargeStaticFile(const path& source, const path& dest)
{
    // First try a hard-link.

    std::error_code ec;
    copy_file(source, dest, copy_options::create_hard_links, ec);

    if (ec)
    {
        // On error, fall-back to a regular copy.  When copying to a different
        // disk, I would expect this error but it does not happen because copy_file
        // ignores the 'create_hard_links' flag and just makes a regular copy

        ec.clear();
        copy_file(source, dest, ec);
    }

    return !ec;
}

但是后来我发现当你调用copy_file时create_hard_link标志并不被执行,如果你想要它被执行,你必须改为调用filesystem::copy。
有人知道为什么吗?有什么技术原因吗?是文件系统规范的疏忽吗?Visual Studio实现有什么问题吗?对我来说毫无意义。
编辑添加:在我发现这一点之后,我确实在copy_options enum中看到了这个标志只适用于copy(),只是不明白它的"为什么"。

fcg9iug3

fcg9iug31#

如果你看一下copy_options的C++标准,你会发现create_hard_links被设计成只影响copy(),而不影响copy_file()。如果你看一下微软的copy_file()实现,你会发现它只关注copy_options中属于“如何处理现有文件”逻辑的部分。
所以不幸的是,微软的STL遵循这里的标准,你试图做的事情根本行不通。
从技术上讲,您甚至在这里避开了未定义的行为:
如果选项中存在的任何copy_options选项组中有多个选项(即使在与filesystem::copy_file无关的组中),则该行为未定义
由于您只指定了create_hard_links,所以从技术上讲,您仍然没有调用UB(而且微软的实现在这里会很宽松),但它根本不会有任何效果。
我不确定,但我猜这里的理由是copy_file被设计成显式复制文件的内容(而不关心花哨的文件系统特性),而copy是一个更高级的例程(标准本身规定copy在某些情况下可以调用copy_file)。
因此,如果需要硬链接,只需使用copy

相关问题