我想使用该std::filesystem::remove()
函数删除一个文件,如果该文件不存在则给出错误。如下所示:
std::error_code errorCode;
if (!std::filesystem::remove("<some file path>", errorCode))
{
std::cout << "Could not delete file because " << errorCode.message();
}
然而,如果该文件不存在,就会出现以下消息Could not delete file because unknown error
。
我的问题是:为什么这没有告诉我该文件不存在?
我对 cppreference 的文档的解释是
error_code
如果文件不存在,则该函数的非版本remove
将返回,false
如果存在其他错误,则抛出异常。- 版本
error_code
遇到任何错误都会返回 false,并将原因存储在 中error_code
。它从不抛出异常。
鉴于文件不存在时错误代码只会显示“未知错误”,似乎此版本提供的信息比非error_code
版本少?或者我误解了什么?
我在 Windows 11 上,使用 Visual Studio 2022 版本 17.11.2。
不,那样会不一致。为什么一个重载将“文件不存在”视为错误并设置
ec
,而另一个重载却不将其视为错误?对于这两个函数来说,不存在文件不是错误。如果文件被成功删除,这两个函数都返回 true,如果文件不存在,则返回 false,
ec
如果发生错误,则报告错误(通过抛出或设置),(可能的错误包括检查文件是否存在失败,或删除文件失败)。这两个重载的行为是一致的。当通过抛出异常来报告错误时,显然没有返回值。当通过设置来报告错误时
ec
,函数仍然必须返回一些内容。最后一句“如果发生错误,带有参数 ec 的签名将返回 false。”告诉你在这种情况下返回什么。它并没有告诉你返回 false 总是意味着发生了错误。或者换句话说,它表示当发生错误时,它返回 false。这与表示当它返回 false 时,意味着发生了错误不同。
由于您没有用特定的操作系统标记问题,并且想知道通用答案,因此我将以基于意见的方式回答。
C++ 标准库依赖于实现。文件系统可能有所不同。您的库实现可能认为“文件不存在”不是错误。
我没有印刷版。下面是最新 C++ 草案的摘录。
您可能已经注意到文件被删除,就好像
POSIX
remove
被调用了一样。Windows 不POSIX
兼容。该库的 Windows 实现可能选择了另一种查看文件删除的方式。更新
为了澄清一些事情,我认为我需要进一步阐述我的答案。请考虑以下该功能的可能实现。
返回值错误将是平台在上述实现返回之前设置的错误。此可能的实现是按照标准措辞完成的。使用我的可能实现,您将从平台获得错误返回。因此,如果您选择我的实现而不是您现在使用的实现,您将获得上述结果。
当文件不存在时,std::filesystem::remove() 在 Windows 上返回“未知错误”的原因在于标准库的某些实现处理缺失文件的错误代码的方式。在这种情况下,它可能无法正确映射错误,从而导致消息模糊。
解决方案:检查错误代码是否为 std::errc::no_such_file_or_directory,它明确表示“找不到文件”:
这对我来说很有效,所以对你来说可能也一样,如果没有用,请随时问我:D