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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章