filelogger.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include "FileLogger.h"
  2. #include <fstream>
  3. #include <ctime>
  4. #include <cstdio> // 用于system()执行目录创建命令
  5. #include <cstring> // 用于strlen(处理char*转string时的长度判断)
  6. // -------------------------- 核心接口实现 --------------------------
  7. void FileLogger::writeToFile(const std::string& relativePath,
  8. const std::string& fileName,
  9. const std::string& data,
  10. WriteMode mode) {
  11. // 1. 拼接完整文件路径(相对路径 + 文件名)
  12. std::string fullPath = joinPath(relativePath, fileName);
  13. // 2. 自动创建目录(若路径不存在)
  14. createDirectory(relativePath);
  15. // 3. 打开文件(根据模式选择打开方式)
  16. std::ofstream file;
  17. if (mode == WriteMode::OVERWRITE) {
  18. // 覆盖模式:ios::trunc 清空文件,ios::out 确保可写
  19. file.open(fullPath, std::ios::out | std::ios::trunc);
  20. } else {
  21. // 追加模式:ios::app 从文件末尾写入,不存在则创建
  22. file.open(fullPath, std::ios::out | std::ios::app);
  23. }
  24. // 4. 检查文件是否成功打开
  25. if (!file.is_open()) {
  26. throw std::runtime_error("Failed to open file: " + fullPath);
  27. }
  28. // 5. 写入数据(带时间戳,便于追溯)
  29. file << data << std::endl;
  30. // 6. 关闭文件(显式关闭更安全,避免缓冲区数据丢失)
  31. file.close();
  32. }
  33. // -------------------------- 辅助函数实现 --------------------------
  34. std::string FileLogger::joinPath(const std::string& path, const std::string& fileName) {
  35. if (path.empty()) {
  36. return fileName; // 路径为空时,直接返回文件名(当前目录)
  37. }
  38. // 检查路径末尾是否已有分隔符,避免重复(如 "log/" + "app.log" → "log/app.log")
  39. if (path.back() == PATH_SEPARATOR[0]) {
  40. return path + fileName;
  41. } else {
  42. return path + PATH_SEPARATOR + fileName;
  43. }
  44. }
  45. void FileLogger::createDirectory(const std::string& relativePath) {
  46. if (relativePath.empty()) {
  47. return; // 无需创建当前目录
  48. }
  49. QString folderPath = QString::fromStdString(relativePath);
  50. QDir folder(folderPath);
  51. if(!folder.exists()){
  52. // 跨平台目录创建命令:Windows用md,Linux用mkdir
  53. std::string cmd;
  54. #ifdef _WIN32
  55. // Windows:md /s 支持多级目录,2>nul 忽略"目录已存在"的错误提示
  56. cmd = "mkdir \"" + relativePath + "\" 2>nul";
  57. #else
  58. // Linux/macOS:mkdir -p 支持多级目录,2>/dev/null 忽略错误提示
  59. cmd = "mkdir -p \"" + relativePath + "\" 2>/dev/null";
  60. #endif
  61. // 执行命令:system()返回0表示成功
  62. int result = system(cmd.c_str());
  63. if (result != 0) {
  64. throw std::runtime_error("Failed to create directory: " + relativePath);
  65. }
  66. }
  67. }