繁体   English   中英

std::filesystem::path 的奇怪运算符/

[英]Strange operator/ of std::filesystem::path

auto path = std::filesystem::path("c:") / "PosteClient.log";

结果 c:PosteClient.log 而不是 c:\PosteClient.log

这对我来说是一个奇怪的行为,因为 windows 上的结果不能使用,例如

CreateFile("c:PosteClient.log")

ERROR_FILE_NOT_FOUND 失败。

我在文档中找不到这种行为的原因,但从示例中看起来这是预期的行为。 https://en.cppreference.com/w/cpp/filesystem/path/append

我想了解为什么会出现这样的行为,以便为我的代码找到合适的解决方案,该解决方案适用于使用此运算符的所有场景

好的,让我们更准确地说,假设我有以下代码:

HANDLE CreateHandleFromPath(const std::filesystem::path& path, const std::string& fileName)
{
    auto pathComplete = path / fileName;

    auto* hFile = CreateFileW(
        pathComplete.wstring().c_str(),
        GENERIC_READ,
        FILE_SHARE_READ, nullptr, OPEN_EXISTING,
        0,
        nullptr);

    if (hFile == INVALID_HANDLE_VALUE || hFile == nullptr)
    {
        throw std::filesystem::filesystem_error(
            "Can't get handle",
            std::error_code(::GetLastError(), std::system_category()));
    }

    return hFile;
}

工作目录是

C:\SRC\ConsoleApplication3\

当我现在调用此代码时

CreateHandleFromPath(std::filesystem::path("c:\\"), "test.log")

function 成功,因为结果路径是“c:\test.log”

CreateHandleFromPath(std::filesystem::path("c:"), "test.log")

function 失败,因为结果路径是“c:test.log”

我无法控制来电者。 当然,在这里进行检查并手动添加分隔符很容易,但这意味着我可以一直自己做,不需要操作员,或者更准确地说,我自己添加更安全,因为这将适用于所有情况,运算符/适用于所有人,除非有人使用没有反斜杠的驱动器号调用。 我只想了解为什么 function 会这样工作,因为我认为有一个我目前看不到的原因

这是因为C:PosteClient.log实际上是一个有效路径,并且很可能与C:\PosteClient.log不同。

关键是 Windows 进程维护每个驱动器的工作目录。

比方说:

  • C:\THING\PosteClient.logD:存在
  • cd C:\THING
  • D:

现在, type C:PosteClient.log可以正确找到您的文件,而C:\PosteClient.log不能(也不应该)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM