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


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

导致c:\PosteClient.log而不是c:\PosteCClient.log

这对我来说是一种奇怪的行为,因为windows上的结果无法使用,例如

CreateFile("c:PosteClient.log")

失败,返回ERROR_FILE_NOT_FOUND。

我在docu中找不到这种行为的原因,但从这个例子来看,这似乎是预期的行为。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")

函数成功是因为结果路径是"0";c: \test.log";

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

函数失败是因为结果路径为"0";c: test.log";

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

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

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

比方说:

存在
  • C:THINGPosteClient.logD:
  • cd C:THING
  • D:

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

最新更新