Qt读取文件对比:每次获取自定义的长度和使用系统的API,耗时对比

news2024/9/21 22:22:50

0. 前言

在编程过程中,经常遇到文件读写操作,太频繁了。每次也都写的不一样。
突发奇想,想测试下几种不同的读取文件的效率。
测试以下三种方式读取文件效率:

  • 自定义读取文件耗时
  • 使用QFile类API读取文件耗时
  • 使用QTextStream类API读取文件耗时

在测试前,说一下使用到的知识点。

1. Qt读取文件

QFile类提供了一个读取和写入文件的接口。
QFile是一个读写文本、二进制文件和资源的I/O设备。QFile可以单独使用,但更多是与QTextStreamQDataStream一起使用。
QFile文件分隔符为’/‘,不分操作系统。不支持使用其他分隔符(例如’'),但可以使用"\\"
如:

QFile file("C:/User/Desktop/in.txt");

QFile file("C:\\User\\Desktop\\in.txt");

可以使用exists()检查文件是否存在,并使用remove()删除文件。(QFileInfoQDir是文件操作相关类)
文件用open()打开,用close()关闭,用flush()刷新。
size()返回文件的大小。可以使用pos()获取当前文件位置,或者使用seek()移动到新的文件位置。如果到达文件的末尾,atEnd()返回true。

QTextStream类为读取和写入文本提供了方便的接口。
QTextStream可以在QIODevice, QByteArrayQString上操作。使用QTextStream的流操作符,可以方便地读取和写入单词,行和数字。

以下是QFileQTextStream读取文件示例

1.1 QFile读取文件

QFile file("C:/User/Desktop/in.txt");
      if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
          return;

      while (!file.atEnd()) {
          QByteArray line = file.readLine();
  // toDoSomething
toDoSomething(line);
      }

以上代码:

  • 先创建一个QFile对象,在构造中设置文件路径
  • 设置打开模式,以只读和文件模式打开
  • 循环读取,当不是文件末尾时,读取行,返回字节数组QByteArray
  • 如果到达末尾,结束循环

1.2 QTextStream读取文件

QFile file("in.txt");
      if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
          return;
      // 创建文本流
      QTextStream in(&file);
      while (!in.atEnd()) {
          QString line = in.readLine();
  // toDoSomething
toDoSomething(line);
      }

以上代码:

  • 先创建一个QFile对象,在构造中设置文件路径
  • 设置打开模式,以只读和文件模式打开
  • 创建文本流,设置I/O设备
  • 循环读取,读取行,返回字符串QString
  • 如果到达末尾,结束循环

2. 自定义读取文件和使用系统API读取耗时对比

以下是三种方式,按行读取,测试所用耗时。
这个是打印函数:

void C_FileParse::printfTest(const int &nLineNum, const QString &ba)
{
    QString strInfo = QString("line : 第 %1 行, info : %2").arg(QString::number(nLineNum), ba);
    // qDebug().noquote() << strInfo;
}

2.1 方式一:自定义读取文件耗时

void C_FileParse::parse()
{
    QElapsedTimer timer;
    timer.start();
    QFile file(m_strFile);
    if(!file.open(QIODevice::ReadOnly))
    {
        return;
    }
    QTextStream in(&file);
    // 如果内容中有中文需要添加以下代码,不然含有中文时乱码
    in.setCodec(QTextCodec::codecForName("UTF-8"));
    QByteArray readInfo;
    int nLineNum = 1;
    while(!in.atEnd())
    {
        readInfo.append(in.read(m_nMaxSize));
        int nPosFind = 0;
        while(true) // 每次解析读到的m_nMaxSize数据
        {
            int nPosTmp = readInfo.indexOf("\r\n", nPosFind);
            if(-1 == nPosTmp) // 当没有找到以"\r\n"为分割的内容时,返回 -1
            {
                if(in.atEnd()) // 判断是否是最后一行
                {
                    // 最后一行,拿file的size() - 最后一个找到的下标nPosFind
                    QByteArray baRowInfo = readInfo.mid(nPosFind, file.size() - nPosFind);
                    // toDoSomething
                    // printfTest(nLineNum++, baRowInfo);
                }else{
                    // 获取非最后一行剩余的部分
                    readInfo = readInfo.right(readInfo.size() - nPosFind);
                }
                break;
            }

            // 获取行数据
            QByteArray baRowInfo = readInfo.mid(nPosFind, nPosTmp - nPosFind);
            // toDoSomething
            // printfTest(nLineNum++, baRowInfo);

            nPosFind = nPosTmp + QString("\r\n").size();
        }
    }
    file.close();
    qDebug().noquote() << "自定义解析:" << timer.elapsed();
}

2…2 方式二:使用QFile类API读取文件耗时

void C_FileParse::parse3()
{
    QElapsedTimer timer;
    timer.start();
    QFile file(m_strFile);
    if(!file.open(QIODevice::ReadOnly))
    {
        return;
    }

    int nLineNum = 1;
    while (!file.atEnd()) {
            // toDoSomething
            // printfTest(nLineNum++, baRowInfo);
    }
    file.close();
    qDebug().noquote() << "QFile自带API的解析:" << timer.elapsed();
}

2.3 方式三:使用QTextStream类API读取文件耗时

void C_FileParse::parse2()
{
    QElapsedTimer timer;
    timer.start();
    QFile file(m_strFile);
    if(!file.open(QIODevice::ReadOnly))
    {
        return;
    }
    QTextStream in(&file);
    // 如果内容中有中文需要添加以下代码,不然含有中文时乱码
    in.setCodec(QTextCodec::codecForName("UTF-8"));
    int nLineNum = 1;
    while (!in.atEnd()) {
            // toDoSomething
            // printfTest(nLineNum++, baRowInfo);
    }
    file.close();
    qDebug().noquote() << "QTextStream自带API的解析:" << timer.elapsed();
}

#3. 结果
调用:

    QString strFile ="C:/User/Desktop/in.txt";
    C_FileParse* pFileParse = new C_FileParse(strFile);

    QtConcurrent::run(pFileParse, &C_FileParse::parse);
    QtConcurrent::run(pFileParse, &C_FileParse::parse2);
    QtConcurrent::run(pFileParse, &C_FileParse::parse3);

image.png
由此可以得出:
还是使用QTextStream进行解析效率最高。
但如果是自定义解析格式,就得用第一种实现方式了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑马程序员Java项目实战《瑞吉外卖》,轻松掌握springboot + mybatis plus开发核心技术的真java实战项目——第四部分

黑马程序员Java项目实战《瑞吉外卖》&#xff0c;轻松掌握springboot mybatis plus开发核心技术的真java实战项目——第四部分 1. 套餐管理1.1 新增套餐1.1.1 添加菜品数据回显 1.2 保存添加套餐1.3 套餐信息分页查询1.4 删除套餐1.5 需要自己单独实现的功能1.5.1 套餐管理的启…

qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

方法一&#xff1a; 如果是https&#xff0c;改为http。 方法二&#xff1a; Qt 解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed问题-CSDN博客 其他&#xff1a;

Elasticsearch零基础实战

分享后可优化点&#xff08;待完成&#xff09; java es8 查询如何打印查询入参 &#xff1f;&#xff08;直接执行的json&#xff09; es自定义分词器 如何实现&#xff1f; kibana 监控jvm分子分母是什么 &#xff1f; es如何 改索引结构&#xff1f; 修改数据原理 分享…

JDBC-数据库连接池(druid)

一、背景 在介绍JDBC基本概念中&#xff0c;似乎Java程序每次与数据库交互都要通过驱动创建一个新的连接对象&#xff08;Connection&#xff09;&#xff0c;再由连接对象创建一个可执行SQL的Statement对象&#xff08;或PreparedStatement对象&#xff09;&#xff0c;操作完…

海康威视摄像头+服务器+录像机配置校园围墙安全侦测区域入侵侦测+越界侦测

一、适用场景 1、校园内&#xff0c;防止课外时间翻越围墙到校外、从校外翻越围墙到校内&#xff1b; 2、通过服务器摄像头的侦测功能及时抓图保存&#xff0c;为不安全因素提供数字化依据&#xff1b; 3、网络录像机保存监控视频&#xff0c;服务器保存抓拍到的入侵与越界&am…

学习笔记16——操作系统

学习笔记系列开头惯例发布一些寻亲消息&#xff0c;感谢关注&#xff01; 链接&#xff1a;https://www.mca.gov.cn/lljz/indexdetail.html?idd0afa7f6f36946319a206d61937f9b63&type0&t10.11199120579373845 八股——操作系统一些基础知识整理 一个java程序对应一个…

腾讯云com域名注册1元一年,非常可以!

腾讯云com域名注册优惠价格1元首年&#xff0c;条件是企业新用户&#xff0c;个人新用户注册com域名是33元首年&#xff0c;第二年续费价格85元一年。活动 txybk.com/go/domain-sales 活动打开如下图&#xff1a; 腾讯云com域名注册优惠价格 腾讯云com域名注册原价是85元一年&a…

*4.3 CUDA MEMORY TYPES

CUDA设备包含几种类型的内存&#xff0c;可以帮助程序员提高计算到全局内存的访问率&#xff0c;从而实现高执行速度。图4.6显示了这些CUDA设备内存。全局内存和恒定内存出现在图片的底部。主机可以通过调用API函数来写入&#xff08;W&#xff09;和读取&#xff08;R&#xf…

PHP反序列化漏洞利用及修复,示例代码讲解

您提到的PHP反序列化漏洞是一个重要的网络安全问题。在我的网络安全工程师的角色下&#xff0c;我可以提供关于此问题的深入分析。 PHP反序列化漏洞通常发生在当不可信的数据被反序列化时。序列化是将数据结构或对象状态转换为可存储或可传输的格式的过程&#xff0c;而反序列…

快速幂算法总结

知识概览 快速幂可以在O(logk)的时间复杂度之内求出来的结果。 例题展示 快速幂 题目链接 活动 - AcWing 系统讲解常用算法与数据结构&#xff0c;给出相应代码模板&#xff0c;并会布置、讲解相应的基础算法题目。https://www.acwing.com/problem/content/877/ 代码 #inc…

机器学习 前馈神经网络

人工神经网络&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09;是指一系列受生物学和神经科学启发的数学模型&#xff0e;这些模型主要是通过对人脑的神经元网络进行抽象&#xff0c;构建人工神经元&#xff0c;并按照一定拓扑结构来建立人工神经元之间的连接…

一文讲透使用Python绘制双纵轴线图

双纵轴线图主要用来展示两个因变量和一个自变量的关系&#xff0c;并且两个因变量的数值单位不同。具体来说&#xff0c;双纵轴线图是指在一幅图上有一个横轴和两个纵轴&#xff0c;适用于三个变量。两个纵轴分别表示一个变量&#xff0c;横轴变量同时适用于两个纵轴上的变量&a…

Selenium-java元素等待三种方式

第二种方式需要写在创建driver时的代码下面 第三种则是对每个定位元素进行配置

Linux基础知识总结

目录 一、Linux权限设置 更改文件属性 chgrp - 更改文件属组 chown - 更改文件所有者&#xff0c;也可以同时更改文件所属组。 chmod - 更改文件属性 二、Linux文件与目录管理 处理目录的常用命令 ls&#xff08;list files&#xff09;- 列出目录及文件名 cd&#xff…

【Linux】Linux系统编程——Linux命令解析器

【Linux】Linux系统编程——Linux命令解析器 什么是Linux 命令解析器&#xff1f; Linux 命令解析器&#xff0c;通常被称为 shell&#xff0c;是 Linux 操作系统中的一个关键组件。它充当用户和系统内核之间的接口&#xff0c;允许用户通过输入命令来控制和管理操作系统和应…

【Spring Cloud】关于Nacos配置管理的详解介绍

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Spring Cloud》。&#x1f3af;&#x1f3af; &am…

Java面试汇总——redis篇

1、什么是缓存穿透 ? 怎么解决 ? 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存就形同虚设&#xff08;只有数据库查到了&#xff0c;才会让redis缓存&#xff0c;但现在的问题是查不到&#xff09;&#xff0c;会频繁的去访问数据库。 解决…

关键字:package关键字

在 Java 中&#xff0c;package关键字用于组织和管理类文件。它将类文件分组到不同的包中&#xff0c;以提供更好的代码组织和可读性。 以下是package关键字的用法&#xff1a; 1.package语句&#xff1a;在 Java 源代码的开头使用package关键字来声明当前类所属的包。例如&a…

基于yolov5的PCB板缺陷检测(附有详细步骤通俗易懂版)

PCB板缺陷检测 模型训练 在初学的时候&#xff0c;可能不太了解到底模型训练是个什么流程&#xff0c;到底是什么意思。其实也很简单&#xff0c;就是我们用一个框架&#xff08;如pytorch&#xff0c;tensorflow等&#xff09;通过一定的算法如yolov5&#xff0c;对一定的数…

Python笔记07-异常、模块和包

文章目录 异常及捕获方法python模块python包安装第三方包 异常及捕获方法 当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是所谓的“异常”, 也就是我们常说的BUG 例如&#xff1a;以r方式打开一个不存在的…