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

源码

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

问题描述

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

思路

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

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

void logfile(std::string fileName, std::string& msg)
{
	// 打开文件(如果尚未打开)
	if (!logFile.is_open()) {
		logFile.open(fileName, std::ios::app);  
		if (!logFile.is_open())
		{
			std::cout << "Error: Unable to open log file." << std::endl;
			std::ios_base::iostate state = logFile.rdstate();
			if (state & std::ios_base::eofbit)
				std::cerr << "End of file reached. ";
			if (state & std::ios_base::failbit)
				std::cerr << "Non-fatal I/O error occurred. ";
			if (state & std::ios_base::badbit)
				std::cerr << "Fatal I/O error occurred. ";
			if (state & std::ios_base::goodbit)
				std::cerr << "No errors. ";
			std::cerr << std::endl;

			// 清除错误状态
			logFile.clear();
			return;
		}
		// 注册退出时的回调函数
		std::atexit(cleanup);
	}
	std::replace(msg.begin(), msg.end(), '\r', ' ');
	// 写入日志
	logFile << msg << std::endl;
	// 强制刷新缓冲区,确保内容写入磁盘
	logFile.flush();
}

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

原因

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

解决办法

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

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

void ZLogManager::ensureDirectoryExists(const std::string& path)
{
	struct stat file_stat;
	if (stat(path.c_str(), &file_stat) != 0) {
#ifdef _WIN32
		if (_mkdir(path.c_str()) != 0) {
			std::cout << "无法创建目录:" << path << std::endl;
			return;
		}
#else 
		if (mkdir(path.c_str(), 0777) != 0) {
			std::cout << "无法创建目录:" << path << std::endl;
			return;
		}
#endif
		std::cout << "目录:" << path << "创建成功" << std::endl;
	}
}

void logfile(std::string fileName, std::string& msg)
{
	size_t last_delimiter = fileName.find_last_of("/\\");
	if (last_delimiter == std::string::npos) {
		std::cout << "非法路径:" << fileName << std::endl;
		return;
	}
	std::string directory_path = fileName.substr(0, last_delimiter);
	ZLogManager::ensureDirectoryExists(directory_path);
	// 打开文件(如果尚未打开)
	if (!logFile.is_open()) {
		logFile.open(fileName, std::ios::app);  
		if (!logFile.is_open())
		{
			std::cout << "Error: Unable to open log file." << std::endl;
			return;
		}
		// 注册退出时的回调函数
		std::atexit(cleanup);
	}
	std::replace(msg.begin(), msg.end(), '\r', ' ');
	// 写入日志
	logFile << msg << std::endl;
	// 强制刷新缓冲区,确保内容写入磁盘
	logFile.flush();
}

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值