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.log
和D:
cd C:THING
D:
现在,type C:PosteClient.log
可以正确地找到您的文件,而type C:PosteClient.log
不能(也不应该(。