当前位置:   article > 正文

C++写数据到文件中报错:Error: Unable to open log file.

C++写数据到文件中报错:Error: Unable to open log file.

源码

  1. void logfile(std::string fileName, std::string& msg)
  2. {
  3. // 打开文件(如果尚未打开)
  4. if (!logFile.is_open()) {
  5. logFile.open(fileName, std::ios::app);
  6. if (!logFile.is_open())
  7. {
  8. std::cout << "Error: Unable to open log file." << std::endl;
  9. return;
  10. }
  11. // 注册退出时的回调函数
  12. std::atexit(cleanup);
  13. }
  14. std::replace(msg.begin(), msg.end(), '\r', ' ');
  15. // 写入日志
  16. logFile << msg << std::endl;
  17. // 强制刷新缓冲区,确保内容写入磁盘
  18. logFile.flush();
  19. }

问题描述

当我测试这个函数时,一直报错无法打开文件

思路

1. 最开始以为是权限问题,路径在E:\\Log盘,检查后并没有问题;

2. 然后加上了详细的输出代码:

  1. void logfile(std::string fileName, std::string& msg)
  2. {
  3. // 打开文件(如果尚未打开)
  4. if (!logFile.is_open()) {
  5. logFile.open(fileName, std::ios::app);
  6. if (!logFile.is_open())
  7. {
  8. std::cout << "Error: Unable to open log file." << std::endl;
  9. std::ios_base::iostate state = logFile.rdstate();
  10. if (state & std::ios_base::eofbit)
  11. std::cerr << "End of file reached. ";
  12. if (state & std::ios_base::failbit)
  13. std::cerr << "Non-fatal I/O error occurred. ";
  14. if (state & std::ios_base::badbit)
  15. std::cerr << "Fatal I/O error occurred. ";
  16. if (state & std::ios_base::goodbit)
  17. std::cerr << "No errors. ";
  18. std::cerr << std::endl;
  19. // 清除错误状态
  20. logFile.clear();
  21. return;
  22. }
  23. // 注册退出时的回调函数
  24. std::atexit(cleanup);
  25. }
  26. std::replace(msg.begin(), msg.end(), '\r', ' ');
  27. // 写入日志
  28. logFile << msg << std::endl;
  29. // 强制刷新缓冲区,确保内容写入磁盘
  30. logFile.flush();
  31. }

再次测试控制台打印:Fatal I/O error occurred.经过查询是致命的输入/输出错误,搜索后发现是路径不存在、文件被其他程序占用、程序没有足够权限读写。检查后发现E盘下没有Log文件夹,找到问题原因。

原因

std::ios::app 会将数据追加到文件上,每次并不清空文件的内容。若文件不存在则创建文件,但是并不会创建路径。

解决办法

1. 最简单的手动在E盘创建一个Log文件夹;

2. 修改代码,判断路径是否存在,如果不存在则创建。下面的代码只包含Windows平台和Linux平台。

  1. void ZLogManager::ensureDirectoryExists(const std::string& path)
  2. {
  3. struct stat file_stat;
  4. if (stat(path.c_str(), &file_stat) != 0) {
  5. #ifdef _WIN32
  6. if (_mkdir(path.c_str()) != 0) {
  7. std::cout << "无法创建目录:" << path << std::endl;
  8. return;
  9. }
  10. #else
  11. if (mkdir(path.c_str(), 0777) != 0) {
  12. std::cout << "无法创建目录:" << path << std::endl;
  13. return;
  14. }
  15. #endif
  16. std::cout << "目录:" << path << "创建成功" << std::endl;
  17. }
  18. }
  19. void logfile(std::string fileName, std::string& msg)
  20. {
  21. size_t last_delimiter = fileName.find_last_of("/\\");
  22. if (last_delimiter == std::string::npos) {
  23. std::cout << "非法路径:" << fileName << std::endl;
  24. return;
  25. }
  26. std::string directory_path = fileName.substr(0, last_delimiter);
  27. ZLogManager::ensureDirectoryExists(directory_path);
  28. // 打开文件(如果尚未打开)
  29. if (!logFile.is_open()) {
  30. logFile.open(fileName, std::ios::app);
  31. if (!logFile.is_open())
  32. {
  33. std::cout << "Error: Unable to open log file." << std::endl;
  34. return;
  35. }
  36. // 注册退出时的回调函数
  37. std::atexit(cleanup);
  38. }
  39. std::replace(msg.begin(), msg.end(), '\r', ' ');
  40. // 写入日志
  41. logFile << msg << std::endl;
  42. // 强制刷新缓冲区,确保内容写入磁盘
  43. logFile.flush();
  44. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号