C++中从文件末尾反向读取N行文件记录。

最近在实际的开发项目遇到了一个问题,有个24小时在跑的Linux程序,会不断有日志输出,写到一个指定的日志文件中。但是,日志只提供了输出的功能,并没有读取日志文件的功能。如果给程序员自己看日志是很简单的,只需要用tail 或 vi 即可。但是现在有个需求,需要在程序的界面上显示日志文件的内容,而且是最近的100行记录。在网上搜索了一遍,总结一下:

1:从文件头开始,先用getline函数获取每一行,然后再丢弃前面的数据。

 我:不行,日志文件有可能几百MB,全部读一篇再丢弃是行不通的。

2:自己先计算文本有多少行,然后再截取。

我:没有找到具体的实现代码,而且我正在读取这个文件时有可能程序正在输出日志,不能随意破坏文件的输出。


最终没找到合适解决方案,我自己的思路是这样的:

1:打开文件

2:将文件指针移到最后。

3:反向搜索换行符,如果达到100行则停止搜索了。

4:根据当前位置再将一行行记录读取放到vector里。

5:现在可以将vector里的记录进行处理。


实现后发现反向读取100的内容还是很快的,0.1毫秒都不用,当然,这要看一行的内容有多少。

而且代码中并不真正去读取字符,只是用C++的io输入流中的peek函数查看数据,效率提高了。

代码如下:


std::ifstream  fin( "/var/log/test.log" , std::ios::ate );
if( !fin )
{
	cerr<<"打开日志文件失败!";
	return -1;
}

// 先倒回文件末尾两个字符
fin.seekg(-2, fin.cur);
// 假定反向读取100行记录
int lineCount = 100;
for(int i = 0; i < lineCount; i++)
{       
	// 查看前一个字符是否为回车符
	while( fin.peek() != fin.widen('\n') )
	{
		fin.seekg(-1, fin.cur );
	}
	// 走到这里表示跳过一行了,所以继续跳直到够100行
	fin.seekg(-1, fin.cur);
}

fin.seekg(2, fin.cur);
// 现在文件指针指向99行的末尾,可以读取了
vector<string> result;
std::string  line;
while( getline(fin, line) )
{
	//cout <<"新入一行 : "; << line << endl;
	result.push_back( line );
}
fin.clear();
fin.close();
</string>


展开阅读全文

没有更多推荐了,返回首页