c++ - 从全局对象的构造函数调用 std::ofstream 时不创建文件
问题描述
首先 - 编写的代码在 Linux 中工作,但在 Windows 上构建和运行时,不会创建日志文件。
我创建了一个简单的日志库,它应该创建一个可执行文件的本地文件。
记录器.h
#ifndef LOGGER_H
#define LOGGER_H
namespace Logger
{
enum class Level
{
DEBUG,
INFO,
WARNING,
ERROR
};
std::string GetTime();
class Log
{
private:
std::string filename;
std::stringstream inStr;
std::ofstream logFile;
std::recursive_mutex inStrMutex;
std::mutex fileMutex;
void ClearStrStream();
std::string LevelToString(Level lvl);
public:
Log(std::string file);
~Log();
template<typename T>
void Write(Level lvl, const T& arg)
{
std::lock_guard<std::recursive_mutex> inStrLock(inStrMutex);
std::lock_guard<std::mutex> fileLock(fileMutex);
inStr << std::noskipws << arg << '\n';
logFile << std::noskipws << "[" << GetTime() << "]"
<< "[" << LevelToString(lvl) << "] "
<< inStr.str();
ClearStrStream();
return;
}
template<typename T, typename... Args>
void Write(Level lvl, const T& firstArg, Args... args)
{
std::lock_guard<std::recursive_mutex> lock(inStrMutex);
inStr << std::noskipws << firstArg;
Write(lvl, args...);
return;
}
};
}
#endif
Logger.cpp 中定义的构造函数
Logger::Log::Log(std::string file) : filename{ file }
{
std::cout << "Ctor called\n";
auto now = Logger::GetTime();
auto fullName = now + "_" + filename;
logFile = std::ofstream(fullName);
inStr = std::stringstream("", std::ios_base::ate | std::ios_base::out | std::ios_base::in);
}
这被构建到一个静态库中,然后链接到 LoggerUnitTest.cpp
#include <chrono>
#include <fstream>
#include <iostream>
#include <mutex>
#include <sstream>
#include <string>
#include <thread>
#include <functional>
#include "Logger.h"
#include "LoggerConfig.h"
#include "date.h"
Logger::Log GLogObject("LoggerTest.log");
void WriteToLogger()
{
GLogObject.Write(Logger::Level::WARNING,
"The quick brown ",
"fox jumps ",
"over the ",
"lazy ",
"dog.");
GLogObject.Write(Logger::Level::ERROR,
"Because nighttime ",
"is the best time ",
"to fight crime.");
return;
}
void TestMultipleTypes()
{
GLogObject.Write(Logger::Level::DEBUG,
"String ",
123,
" and integer.");
return;
}
int main()
{
std::cout << "Testing Logger Version: " << LOGGER_VERSION_MAJOR << "."
<< LOGGER_VERSION_MINOR << std::endl;
std::thread t1(TestMultipleTypes);
std::thread t2(WriteToLogger);
WriteToLogger();
std::thread t3(WriteToLogger);
WriteToLogger();
std::thread t4(WriteToLogger);
std::thread t5(WriteToLogger);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
return 0;
}
当 LoggerUnitTest 在 Linux 中构建并运行时,一切都按预期工作。创建一个日志文件,并将所有内容按预期写入日志文件。
在 Windows 中构建和运行 LoggerUnitTest 时,LoggerUnitTest.exe 会运行,但不会创建日志文件。Windows 有什么不同导致没有文件被写入?
我还尝试显式添加std::flush
Logger 的 Write 函数,这似乎没有什么区别。
解决方案
问题在于 GetTime() 返回日期/时间格式字符串的方式。甲酸盐为 YYYY/mm/DD_HH:MM:SS。根据Microsoft Docs,冒号:
和正斜杠/
是文件名中的禁止字符。调整日期/时间格式后,一切正常!
推荐阅读
- java - 在tomcat服务器mac os上部署/启动可流动的war文件
- javascript - MeshPhongMaterial 上的三个 js RectAreaLight 没有光反射(不支持 OES_texture_half_float)
- mongodb - 我该如何解决 UnhandledPromiseRejectionWarning: MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017
- jestjs - Jest 无法使用带有错误消息的 Mock 文件运行您的测试套件必须包含至少一个测试
- reactjs - 跨多个选项卡共享会话数据
- java - 不太清楚为什么“计数”中途减少(java)
- css - CSS:动态生成的纵横比,填充容器的高度,但保持所需的纵横比并且永远不会溢出视口
- python - 使用写入给定路径的给定字典创建一个新字典
- node.js - 下一个 js API 在没有发送 /api/contact 响应的情况下解析,这可能会导致请求停止
- google-sheets - Google 表格 - 条件格式:突出显示包含在列表中找到的文本的单元格(动态列表)