QT处理日志文件

由于实际生产需要,软件系统的运行,会产生大量的日志文件,有时候一天就能产生超过百万条log记录,那么为了能够处理日志文件,查询并且找到我们想要的报错信息,因此不得不考虑怎么实现,打开大日志文件的可行方法。

在这里我采用的是内存映射的方式去读取文件的日志信息。代码部分如下所示:

QFile file(big_path);
qint64 fileSize = file.size(); // 获取文件的大小
uchar *data = file.map(0, fileSize); // 将文件的全部内容映射到内存中,返回一个指向该内容的指针
file.close();//文件的关闭不会影响到我们后续的内存映射部分。if (data) { // 如果映射成功QElapsedTimer timer;timer.start();message.clear();QString text = QString::fromUtf8((char *)data, fileSize);file.unmap(data); // 取消映射ui->plainTextEdit->appendPlainText(text);message=text.split("\n");ui->label->setText("识别完成,时间为:"+QString::number(timer.elapsed()/1000)+"s");QTextCursor cursor = ui->plainTextEdit->textCursor();cursor.movePosition(QTextCursor::Start);ui->plainTextEdit->setTextCursor(cursor);//是为了实现将鼠标对应的光标移动到第一行,也就是日志的最上面。}else { // 如果映射失败qDebug() << "映射失败,错误信息:" << file.errorString(); // 打印错误信息QMessageBox::information(this,"提示","映射失败,错误信息:"+file.errorString());}

QT里面的内存映射的机制如下:

内存映射(Memory Mapping)是一种将文件或者设备的一部分映射到进程的虚拟地址空间的技术,这样可以方便地对文件或者设备进行读写操作,而不需要使用系统调用或者缓冲区。QT提供了QFileDevice类和QFile类来支持内存映射的功能,相关的方法有:

  • map(qint64 offset, qint64 size, QFileDevice::MemoryMapFlags flags = NoOptions):这个方法可以将文件或者设备的一部分映射到内存中,并返回一个指向该内存区域的指针。参数offset表示映射的起始位置,size表示映射的大小,flags表示映射的选项,比如是否保护、是否共享等。
  • unmap(uchar *address):这个方法可以取消内存映射,并释放相关的资源。参数address表示要取消映射的内存区域的指针。
  • isMapped(uchar *address):这个方法可以检查一个内存区域是否是由map()方法映射的。参数address表示要检查的内存区域的指针。

除此之外,还有如何搜寻自己想要的信息,方式有以下几种:

首先,第一种是遍历循环每一条log信息,并在其中进行搜索,但是这样的搜索方式只能用于小日志文件,当文件内容过多的时候,这种搜索方式的时间度是很大的。

利用for或者while等循环,来遍历每一条的log信息。但是这个遍历出来的速度和效率是十分慢的。

代码实现如下所示:

 qDebug()<<pp;path_text=pp;message.clear();// 创建一个QFile对象,关联用户选择的文件QFile file(path_text);// 以只读模式打开文件if (file.open(QIODevice::ReadOnly)) {// 循环读取每一行// 创建一个QTextStream对象,关联文件QTextStream in(&file);// 设置流对象的编码为UTF-8in.setCodec("UTF-8");while (!file.atEnd()) {// 读取一行内容,转换为QString类型QString line = QString::fromUtf8(file.readAll());// 处理或显示每一行内容message.append(line);qDebug()<<line;ui->plainTextEdit->appendPlainText(line);//appendPlainText}// 关闭文件file.close();}else{qDebug() <<"error";}

这里为了加快读取的速度,还专门设置了文件的编码形式为UTF-8,来减少QT的自动识别编码的时间,而且这个读取文件的方式是用的Qtextstream的方式来的。

第二种就是,由于笔记本上面自带的软件记事本而想到的一种方式,就是记事本的查询功能的实现,因此考虑到,将同样的功能实现在QT里面。

另外,上面也说过了需要实现log文件的显示,在这里我采用的是Qplaintext控件来显示大量的文本信息。注意在这里不能采用textedit编辑器来显示大容量的文本,它会出现错误。

我的界面设计如下所示:

 因为我需要查找信息,因此,要将用户的输入的信息进行筛选,所以我还用了一个linedit的控件来获取输入内容。

实现查找信息的功能的代码部分如下图所示:

QString goal=ui->lineEdit->text();bool result=ui->plainTextEdit->find(goal);//向下寻找
// bool result2=ui->plainTextEdit->find(goal,QTextDocument::FindBackward);//向回找if(result){QTextCursor cursor = ui->plainTextEdit->textCursor();qDebug()<<cursor.blockNumber();shunxu.push_back(cursor.blockNumber());return true;}return false;

我通过QT给的封装函数,find函数,它会帮助我找到符合我需要的内容的所在下一行,并且将光标移动到这一行,然后我再利用QTextCursor来获取当前光标所在行数的位置,并且打印保存下来。

因为我在前面的ui->plaintext里面,将获取得到的log内容,通过QString里面的split(“\n”)函数的方式将原来的QString的内容按行分割成QStringList的形式保存下来。然后我通过前面获得的行号,将对应的Qtring的行的内容,取出来,并且显示ui->plaintext上面即可。

这种遍历方式也最多只能达到同时遍历几百行的样子。

第二种方式也可以优化,比如可以分成两部分,多开一个线程,让其中一个从最后开始寻找,主线程从第一行开始寻找,最后将找到的日志行数汇总到一起。相当于是一个简单的二分法寻找。

最后第三种方式:同时遍历很多行数

这个方法的时间复杂度是O(n),也就是随着元素的数量增加,所需的时间也会线性增加。如果您想要一次遍历很多行,也就是提高查找的效率,您可以使用以下的方法:

  • 使用QHash或者QMap类来存储每个元素和它们的索引或者计数,这样可以实现O(1)或者O(log n)的查找时间,但是需要额外的空间来存储哈希表或者映射表。
  • 使用QStringList类的filter()方法来过滤出包含指定内容的元素,然后使用indexOf()方法或者contains()方法来获取它们的索引或者计数,这样可以减少遍历的次数,但是需要创建一个新的QStringList对象。
  • 使用QRegularExpression类来创建一个正则表达式对象,表示您想要查找的内容,然后使用QStringList类的indexOf()方法或者contains()方法来查找匹配该正则表达式的元素,并获取它们的索引或者计数,这样可以更灵活地定义查找的条件,但是需要注意正则表达式的语法和效率。

代码部分如下所示:

#include <QApplication>
#include <QPlainTextEdit>
#include <QDebug>
#include <QRegularExpression>int main(int argc, char *argv[]) {QApplication app(argc, argv);QPlainTextEdit *edit = new QPlainTextEdit(); // create a QPlainTextEdit objectedit->setPlainText("This is a test text for QPlainTextEdit.\nIt may have multiple lines.\nSome lines may contain the word function."); // set some plain textQString text = edit->toPlainText(); // get the plain text contentQStringList lines = text.split("\n"); // split the text by newlineQRegularExpression re("\\bfunction\\b"); // create a regular expression object, using \b to match word boundariesint count = 0; // the number of lines that match the regular expressionint index = -1; // the index of the first matching linewhile ((index = lines.indexOf(re, index + 1)) != -1) { // loop through the lines, using indexOf() method to find the matching linecount++; // increase the countqDebug() << "Found" << re.pattern() << "at line" << index + 1; // print the line number, add 1 because the index is zero-based}qDebug() << "Total" << count << "lines match" << re.pattern(); // print the total countreturn app.exec();
}

QHash和QMap都是Qt提供的关联容器类,它们可以用来存储键值对的数据结构。它们的主要区别是:

  • QHash是基于哈希表实现的,它的查找速度通常比QMap更快,但是它的键是以任意顺序存储的,而且它对键的类型有更多的要求,需要提供operator==()和qHash()函数。
  • QMap是基于跳表实现的,它的查找速度通常比QHash慢一些,但是它的键是以升序顺序存储的,而且它对键的类型只需要提供operator<()函数。

如果您需要时间度最小的一种遍历方法,我建议您使用QHash,并且使用STL风格的迭代器来遍历。这样可以避免创建额外的对象,并且可以直接访问键和值。例如:

QHash<QString, QStringList> hash;
// insert some data into hash
QHash<QString, QStringList>::const_iterator i = hash.constBegin();
while (i != hash.constEnd()) {QString key = i.key();QStringList value = i.value();// do something with key and value++i;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/95386.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CFD特性FPmarkets澳福认为了解这11种足够了

CFD在交易中很重要&#xff0c;但CFD特性很多投资者不了解&#xff0c;FPmarkets澳福认为了解这11种足够了&#xff1a; 1. 投资者通过标的资产价格价值的变化获利&#xff0c;而不拥有标的资产。 2. 差价合约交易没有固定的到期日。 3. 与期货交易类似&#xff0c;差价合约交易…

python自动化办公的一些小工具,函数组件

上一篇文章写了怎么自动化写一个月报&#xff0c;其中有很多很好用的函数组件&#xff0c;都被我封装为了函数&#xff0c;功能很好用。下面一一介绍&#xff1a; 1.添加汇总函数 输入一个pandas的数据框&#xff0c;就会返回一个加了汇总行的数据框。 def add_summary_row(d…

慎投!新增4本期刊被“On Hold”!快自查

又新增了被标记的期刊&#xff01;截至目前&#xff0c;小编从科睿唯安旗下的“Master Journal List”官网查到&#xff0c;本次新增4本ESCI期刊被标记&#xff0c;目前有8本SCIE期刊&#xff0c;1本SSCI期刊&#xff0c;13本ESCI期刊&#xff0c;共22本期刊被标记为“On Hold”…

c++游戏制作指南(四):c++实现数据的存储和读取(输入流fstream)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到静渊隐者的csdn博文&#xff0c;本文是c游戏制作指南的一部&#x1f35f; &#x1f355;更多文章请点击下方链接&#x1f355; &#x1f368; c游戏制作指南&#x1f3…

超声波传感器(HC-SR04)按时序图手撕驱动

目录 1、简介 2、传感器介绍 2.1 引脚介绍 2.2 时序图介绍 3、 需求与接线 3.1 任务需求 3.2 接线 4、Cubemax配置 4.1 SYS配置 4.2 RCC配置 4.3 时钟树配置 4.4 GPIO初始化 4.5 定时器配置 4.6 生成代码 5、 keil端代码编写 5.1 微妙函数封装 5.2 超声波驱动封装…

生信豆芽菜-差异基因富集分析

网址&#xff1a;http://www.sxdyc.com/enrichmentEnrich 该工具使用R 语言的clusterProfiler包对关键基因集进行GO和KEGG富集分析&#xff0c;注意这个的关键基因集可以是差异基因&#xff0c;WGCNA的module基因&#xff0c;也可以是表型相关的基因集 1、数据准备 准备一个基因…

SpringBoot系列之基于Jersey实现RESTFul风格文件上传API

前言 JAX-RS&#xff1a;JAX-RS是可以用可以用于实现RESTFul应用程序的JAVA API&#xff0c;给开发者提供了一系列的RESTFul注解Jersey&#xff1a;是基于JAX-RX API的实现框架&#xff0c;用于实现RESTful Web 服务的开源框架。 JAX-RX常用的注解&#xff1a; javax.ws.rs.Pa…

【网络编程·网络层】IP协议

目录 一、IP协议的概念 二、IP协议的报头 1、四位首部长度 2、16位总长度&#xff08;解包&#xff09; 3、8位协议&#xff08;分用&#xff09; 4、16位首部校验和 5、8位生存时间 6、32位源IP和32位目的IP 7、4位版本/8位服务类型 8、16位标识 9、3位标志 10、1…

IDEA 设置为护眼的豆沙绿

代码区域设置成护眼色 先打开 IDEA 的设置界面&#xff0c;然后按照下图按顺序店了设置就可以了 这个时候&#xff0c;可以看到&#xff0c;只有代码区域别成了护眼色&#xff0c;其他地方还是白的刺眼&#xff0c;我们来一个一个的解决掉 左侧的文件页修改为护眼色 还是先…

基于YOLOv8模型的五类动物目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型的五类动物目标检测系统可用于日常生活中检测与定位动物目标&#xff08;狼、鹿、猪、兔和浣熊&#xff09;&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与…

【Vue-Router】路由传参

1. query 传参 list.json {"data": [{"name": "面","price":300,"id": 1},{"name": "水","price":400,"id": 2},{"name": "菜","price":500,"…

uniapp+uview封装小程序请求

提要&#xff1a; uniapp项目引入uview库 此步骤不再阐述 1.创建环境文件 env.js&#xff1a; let BASE_URL;if (process.env.NODE_ENV development) {// 开发环境BASE_URL 请求地址; } else {// 生产环境BASE_URL 请求地址; }export default BASE_URL; 2.创建请求文件 该…

数据结构--算法的时间复杂度和空间复杂度

文章目录 算法效率时间复杂度时间复杂度的概念大O的渐进表示法计算实例 时间复杂度实例 常见复杂度对比例题 算法效率 算法效率是指算法在计算机上运行时所消耗的时间和资源。这是衡量算法执行速度和资源利用情况的重要指标。 例子&#xff1a; long long Fib(int N) {if(N …

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取

OpenCV-Python中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 Python-OpenCV中的图像处理-GrabCut算法交互式前景提取 cv2.grabCut(img: Mat, mask: typing.Optional[Mat], rect, bgdModel, fgdModel, iterCount, mode…) img…

华为云零代码新手教学-体验通过Astro Zero快速搭建微信小程序

您将会学到 您将学会如何基于Astro零代码能力&#xff0c;DIY开发&#xff0c;完成问卷、投票、信息收集、流程处理等工作&#xff0c;还能够在线筛选、分析数据。实现一站式快速开发个性化应用&#xff0c;体验轻松拖拽开发的乐趣。 您需要什么 环境准备 注册华为云账号、实…

基于Helm管理Kubernetes应用

Kubernetes部署方式 官方提供Kubernetes部署3种方式 minikube Minikube是一个工具&#xff0c;可以在本地快速运行一个单点的Kubernetes&#xff0c;尝试Kubernetes或日常开发的用户使用。不能用于生产环境。 官方文档&#xff1a;Install Tools | Kubernetes 二进制包 从…

如何从cpu改为gpu,pytorch,cuda

1.cmd输入nvcc -V 2.得到 cuda版本后&#xff0c;去pytorch官网 3.根据自己的cuda进行选择 4.复制上述链接&#xff0c;进入cmd 5.cmd中输入activate XXX,这里的"XXX"指代自己在工程中用到的环境 6.进入后&#xff0c;将刚才链接粘贴&#xff0c;回车等待下载结束 …

Linux 基础

巩固基础&#xff0c;砥砺前行 。 只有不断重复&#xff0c;才能做到超越自己。 能坚持把简单的事情做到极致&#xff0c;也是不容易的。 linux的目录结构 linux的文件系统采用树状的目录结构&#xff0c;在此结构的最上层是根目录“/”&#xff0c; 然后在此目录下再创建其他…

Mirror网络库 | 实战

此篇为下文&#xff0c;上篇&#xff1a;Mirror网络库 | 说明 一、官方实例说明 场景名说明AdditiveLevels场景为“关卡”&#xff0c;附加形式加载AdditiveScenes加载卸载附加场景Basic基础的连接/断开&#xff0c;消息发送Benchmark服务器1000“怪物”生成性能测试Benchmark…

IL汇编ldc指令学习

ldc指令是把值送到栈上&#xff0c; 说明如下&#xff0c; ldc.i4 将所提供的int32类型的值作为int32推送到计算堆栈上&#xff1b; ldc.i4.0 将数值0作为int32推送到计算堆栈上&#xff1b; ... ldc.i4.8 将数值8作为int32推送到计算堆栈上&#xff1b; ldc.i4.m1 将数值-…