#include "FileLogger.h" #include #include #include // 用于system()执行目录创建命令 #include // 用于strlen(处理char*转string时的长度判断) // -------------------------- 核心接口实现 -------------------------- void FileLogger::writeToFile(const std::string& relativePath, const std::string& fileName, const std::string& data, WriteMode mode) { // 1. 拼接完整文件路径(相对路径 + 文件名) std::string fullPath = joinPath(relativePath, fileName); // 2. 自动创建目录(若路径不存在) createDirectory(relativePath); // 3. 打开文件(根据模式选择打开方式) std::ofstream file; if (mode == WriteMode::OVERWRITE) { // 覆盖模式:ios::trunc 清空文件,ios::out 确保可写 file.open(fullPath, std::ios::out | std::ios::trunc); } else { // 追加模式:ios::app 从文件末尾写入,不存在则创建 file.open(fullPath, std::ios::out | std::ios::app); } // 4. 检查文件是否成功打开 if (!file.is_open()) { throw std::runtime_error("Failed to open file: " + fullPath); } // 5. 写入数据(带时间戳,便于追溯) file << data << std::endl; // 6. 关闭文件(显式关闭更安全,避免缓冲区数据丢失) file.close(); } // -------------------------- 辅助函数实现 -------------------------- std::string FileLogger::joinPath(const std::string& path, const std::string& fileName) { if (path.empty()) { return fileName; // 路径为空时,直接返回文件名(当前目录) } // 检查路径末尾是否已有分隔符,避免重复(如 "log/" + "app.log" → "log/app.log") if (path.back() == PATH_SEPARATOR[0]) { return path + fileName; } else { return path + PATH_SEPARATOR + fileName; } } void FileLogger::createDirectory(const std::string& relativePath) { if (relativePath.empty()) { return; // 无需创建当前目录 } QString folderPath = QString::fromStdString(relativePath); QDir folder(folderPath); if(!folder.exists()){ // 跨平台目录创建命令:Windows用md,Linux用mkdir std::string cmd; #ifdef _WIN32 // Windows:md /s 支持多级目录,2>nul 忽略"目录已存在"的错误提示 cmd = "mkdir \"" + relativePath + "\" 2>nul"; #else // Linux/macOS:mkdir -p 支持多级目录,2>/dev/null 忽略错误提示 cmd = "mkdir -p \"" + relativePath + "\" 2>/dev/null"; #endif // 执行命令:system()返回0表示成功 int result = system(cmd.c_str()); if (result != 0) { throw std::runtime_error("Failed to create directory: " + relativePath); } } }