获取 std::ofstream open 失败的描述性原因

Get a descriptive reason why std::ofstream open failed

提问人:M. Victor 提问时间:10/20/2023 最后编辑:M. Victor 更新时间:10/23/2023 访问量:77

问:

是否有标准/跨平台的方法可以抛出描述性异常以及文件无法打开的原因?(例如:“只读目录”、“权限被拒绝”、“文件在另一个程序中打开”等)

我从某个调用者那里接收到一个文件,我需要写入/创建该文件,如果出现错误,则抛出异常。SomeMethod

我尝试像这样使用成员函数:ofstream::exceptions

void SomeMethod(std::string fileName)
{
  std::ofstream outFile;
  outFile.exceptions(std::ios::failbit | std::ios::eofbit);
  outFile.open(fileName);

  // start writing to file..
}

但是抛出的异常不够描述。我得到:

ios_base::failbit set: iostream stream 错误

我也尝试使用:std::system_error

void SomeMethod(std::string fileName)
{
  std::ofstream outFile(fileName);
  if (!outFile.is_open())
  {
    throw std::system_error(
#ifdef _WIN32
      ::GetLastError(),
#else
      errno,
#endif
      std::system_category(), "Error opening " + fileName);
  }

  // start writing to file..
}

这给出了我想要的描述性错误:

打开 some_file.txt 时出错:只读文件系统

但是,代码有点太冗长了。我希望有更短的东西......

我创建了这个游乐场:https://godbolt.org/z/b1zKKnEnz

C++ 文件 异常 系统 fstream

评论

3赞 gerum 10/20/2023
如果你已经有一个errno,你可以使用std::strerror来获取文本描述。
0赞 AngelosFr 10/20/2023
我也有类似的疑惑,并在这里发表了这篇文章。codereview.stackexchange.com/questions/269182/......如果你愿意,可以看看
0赞 Remy Lebeau 10/21/2023
您可以简单地将 / 包装在辅助函数或宏中,例如: 或 ,然后在语句中使用它:GetLastError()errnoint getMyLastError() { #ifdef _WIN32 return ::GetLastError(); #else return errno; #endif }#ifdef _WIN32 #define getMyLastError() ::GetLastError() #else #define getMyLastError() errno #endifthrowthrow std::system_error(getMyLastError(), std::system_category(), "Error opening " + fileName);
0赞 M. Victor 10/23/2023
@gerum std::strerror 需要更多的 #ifdefs,因为它已被 msvc 弃用(除了 #ifdef arround errno 和 GetLastError)
0赞 gerum 10/24/2023
@M.Victor:你要求一个标准的方法来解决这个问题。errno(C 标准)和 std::errno 都是 thr 标准的一部分。

答: 暂无答案