C++遍歷日誌log目錄,並提取資料進行分析
1 前言
我們經常在編寫軟體的時候,需要載入log檔案來記錄程式執行過程中可能會出現的bug,或者記錄一些重要的執行資訊。一旦一個目錄下生成很多log檔案後,實際上我們管理與分析還是需要費一些時間的。這其中就需要我們懂得怎樣讀取log檔案,怎樣遍歷目錄,怎樣解析資料等等一系列操作。
下面我們直接通過一個例項來了解各個部分是如何實現的,這個例項的要求如下:
①、D盤log目錄下有很多.log檔案,我們需要從每個檔案中提取資料(隱藏兩個任務:開啟讀取檔案;遍歷目錄);
②、我們需要從檔案中提取speed關鍵字後面對應的資料放入到Excel表格.csv檔案中。
2 程式實現
2.1 讀取檔案
以前從C開始我們就學習了使用fopen()開啟檔案,fread()讀取資訊,後來由於存在不安全性,又有了類似的fopen_s()相關定義。但是本次我們使用更上層一些的流操作來讀取檔案,該類方法定義在#include<fstream>
中,實現如下:
#include<fstream>
using namespace std;
void GetLog(const string& file)
{
//string file = "D:/log/1.log";// 放置log檔案的目錄
ifstream logFile(file); // 構造一個檔案流讀取物件
string str;
while (getline(logFile, str)) // 隔行讀入資料
{
// ... // 資料處理部分
str.clear(); // 重複載入,所以每次需要清空
}
logFile.close(); // 關閉檔案
}
上面的ifstream類是用來構造讀取檔案物件的類,對應還有構造輸出到檔案的物件的類ofstream。如果既存在讀入和存取,有fstream類,根據自己的需要定義對應的類,然後後面我們就可以像終端上流輸入輸出一樣處理載入的資料。
2.2 遍歷日誌目錄
有了上面的檔案讀取功能函式,下面我們來看看如何載入一個目錄下所有log檔案來進行讀取與分析。這裡主要用到#include<io.h>
標頭檔案中定義的_findfirst()和_findnext()函式介面來依次讀取所有檔案,以及構造結構體 _finddata_t物件來儲存目錄下檔案基本資訊。我們還是直接看程式:
#include<string> // 字串類
#include<io.h> // 遍歷操作
struct _finddata_t fileinfo; // 儲存檔案資訊的結構體物件
string file = "D:/log/"; // 放置log檔案的目錄
string strFile = file + "*.log";
/***遍歷目錄系統函式要求先嚐試尋找一個檔案,看是否存在***/
long handle;
if ((handle = _findfirst(strFile.c_str(), &fileinfo)) == -1L)
{
return 0; // 如果查詢log檔案失敗,直接返回
}
else
{
strFile = file + fileinfo.name;
GetLog(strFile); // 對第一個載入的檔案處理
/***一直遍歷,直到所有.log檔案得到載入與處理***/
while (!(_findnext(handle, &fileinfo)))
{
strFile = file + fileinfo.name;
GetLog(strFile); // 檔案處理
}
coutReport.close(); // 釋放檔案載入
_findclose(handle); // 釋放遍歷目錄的控制程式碼
}
2.3 資料處理
我們的案例中是一個小小的處理要求,就是對log檔案下提取一下speed關鍵字後面記錄的資料。這裡提取資料並一一對所有字串處理的操作主要用到定義在#include<sstream>
中字串流操作的stringstream類。跟fstream中定義的一樣,istringstream類是從檔案讀入資料,而ostringstream類是將資料存入檔案,而stringstream類就是兩種操作都可以。程式如下:
#include<sstream> // 字串流操作
#include<string> // 字串類
#include<io.h> // 遍歷操作
using namespace std;// 標準庫名稱空間
const char* coutFile = "D:/log/output.csv"; // 輸出提取資料到csv檔案
// 上面隔行讀入的資料
while (getline(logFile, str))
{
stringstream strRead(str);
string oneWord;
while (strRead >> oneWord) // 一個個word載入進去
{
if (oneWord.compare("Speed") == 0) // 字串查詢
{
int result;
strRead >> result; // Speed後面的數字輸出到result中
cout << result << endl; // 寫入檔案,並且空行
}
}
str.clear(); // 重複載入,所以每次需要清空
}
3 完整參考程式
#include<iostream> // cin、cout
#include<fstream> // 包含檔案讀取類與方法
#include<sstream> // 字串流操作
#include<string> // 字串類
#include<io.h> // 遍歷操作
using namespace std;// 標準庫名稱空間
string file = "D:/log/"; // 放置log檔案的目錄
const char* coutFile = "D:/log/output.csv"; // 輸出提取資料到csv檔案
ofstream coutReport(coutFile); // 構建輸出結果檔案類物件
void GetInfo(const string& filePath)
{
ifstream logFile(filePath);
string str;
// 隔行讀入資料
while (getline(logFile, str))
{
stringstream strRead(str);
string oneWord;
while (strRead >> oneWord) // 一個個word載入進去
{
if (oneWord.compare("Speed") == 0)
{
int result;
strRead >> result; // Speed後面的數字輸出到result中
cout << result << endl; // 寫入檔案,並且空行
}
}
str.clear(); // 重複載入,所以每次需要清空
}
// 關閉檔案
logFile.close();
}
int main()
{
struct _finddata_t fileinfo;
string strFile = file + "*.log";
/***遍歷目錄系統函式要求先嚐試尋找一個檔案,看是否存在***/
long handle;
if ((handle = _findfirst(strFile.c_str(), &fileinfo)) == -1L)
{
return 0; // 如果查詢log檔案失敗,直接返回
}
else
{
strFile = file + fileinfo.name;
GetInfo(strFile); // 檔案處理
/***一直遍歷,直到所有.log檔案得到載入與處理***/
while (!(_findnext(handle, &fileinfo)))
{
strFile = file + fileinfo.name;
GetInfo(strFile); // 檔案處理
}
coutReport.close(); // 釋放檔案載入
_findclose(handle); // 釋放遍歷目錄的控制程式碼
}
return 0;
}
以上是個人學習記錄,由於能力和時間有限,如果有錯誤望讀者糾正,謝謝!
轉載請註明出處:http://blog.csdn.net/FX677588/article/details/76473528
相關文章
- Linux伺服器使用Redis作為資料快取,並用log4j2進行日誌記錄Linux伺服器Redis快取
- Godot遍歷目錄下檔案,並建立按鈕Go
- 什麼是目錄遍歷?
- 提取pdf目錄,並且分級
- oracle 12C RAC 12.1.0.2 叢集日誌(cluster log)目錄Oracle
- Oracle listener log 日誌分析方法Oracle
- MySQL更新資料時,日誌(redo log、binlog)執行流程MySql
- 遍歷目錄下的所有檔案
- log4net日誌記錄
- php遍歷資料夾以及子目錄;PHP
- 如何對資料目標進行分析
- <Zhuuu_ZZ>Spark專案之log日誌資料分析處理Spark
- 目錄遍歷-基於Pikachu的學習
- Log日誌
- .Net Core(.NET6)中接入Log4net和NLog進行日誌記錄
- 資料遍歷
- Gin 框架 - 使用 logrus 進行日誌記錄框架
- Sqlserver2016啟用了日誌並行,但是實際上某些資料庫日誌並行並沒有生效的問題SQLServer並行資料庫
- golang對遍歷目錄操作的最佳化Golang
- 如何將 winston log 庫記錄的日誌寫入 mongo DB 資料庫Go資料庫
- Flume收集日誌到本地目錄
- C++ 遍歷queueC++
- 使用Java和Elastic Stack進行日誌分析JavaAST
- log 日誌原理
- Python 日誌(Log)Python
- indexedDB 遍歷資料Index
- .Net Core中使用DiagnosticSource進行日誌記錄
- 通過DataWorks資料整合歸檔日誌服務資料至MaxCompute進行離線分析
- Oracle 例項和RAC叢集下資料庫日誌目錄合集Oracle資料庫
- 網路安全中的目錄遍歷指什麼?
- c++ 獲取資料夾目錄名字C++
- Shell 指令碼迴圈遍歷日誌檔案中的值進行求和並計算平均值,最大值和最小值指令碼
- [譯] 在 Python 中,如何運用 Dask 資料進行並行資料分析Python並行
- Log 工具列印日誌
- Linux C日誌logLinux
- 記錄遍歷方法
- 【LOG】Oracle資料庫清理日誌、跟蹤檔案利器Oracle資料庫
- Django筆記三十之log日誌記錄詳解Django筆記
- Windows服務使用log4net記錄日誌Windows