禁止“重命名”复制文件

时间:2019-05-15 14:29:19

标签: c++

如果Windows 10指向其他驱动器,

rename实际上会复制文件(至少在newname平台上)。

有办法避免这种情况吗?我希望它在这种情况下失败。

假设我要移动100 GB的文件。如果可能的话,我想将其重命名。如果没有,我想使用我自己的复制功能并向用户显示操作进度。

2 个答案:

答案 0 :(得分:3)

您可以尝试创建到新目的地的硬链接。如果失败,则失败。如果成功,则删除原始文件。我验证了它适用于Linux(g ++ 8.3.1和clang ++ 7.0.1)和Windows(VS2019)上的文件(而非目录),并希望它也可以在大多数其他现代OS:es上使用。需要C ++ 17(或旧编译器为boost)。

#include <filesystem>
#include <iostream>
#include <string_view>
#include <vector>

bool my_rename(const std::string_view from, const std::string_view to,
               std::error_code& ec)
{
    // create hard link
    std::filesystem::create_hard_link(from, to, ec);

    if(ec) return false; // it failed

    // remove the original
    return std::filesystem::remove(from, ec);
}

int cppmain(const std::string_view program, std::vector<std::string_view> args) {
    if(args.size() != 2) {
        std::cerr << "USAGE: " << program << " <source> <target>\n";
        return 1;
    }

    std::error_code ec;

    if(my_rename(args[0], args[1], ec) == false) {
        std::cerr << program << ": " << ec << "\n";
        return 1;
    }

    return 0;
}

int main(int argc, char* argv[]) {
    return cppmain(argv[0], {argv + 1, argv + argc});
}

答案 1 :(得分:2)

如果在Windows中,则可以使用MoveFileEx而不使用MOVEFILE_COPY_ALLOWED。 您还可以使用GetVolumePathNameW来确定源和目标是否属于同一卷,因此可以确定是否(可能)需要一个副本。