C++遍历日志log目录,并提取数据进行分析

来源:互联网 发布:程序员怀疑手游被抄袭 编辑:程序博客网 时间:2024/06/03 03:35

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

原创粉丝点击