首页 > 其他分享 >Qt读取文件对比:每次获取自定义的长度和使用系统的API,耗时对比

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

时间:2024-01-08 23:01:49浏览次数:29  
标签:文件 读取 自定义 QFile file FileParse QTextStream 对比 Qt

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进行解析效率最高。 但如果是自定义解析格式,就得用第一种实现方式了。

标签:文件,读取,自定义,QFile,file,FileParse,QTextStream,对比,Qt
From: https://blog.51cto.com/u_16417016/9151875

相关文章

  • elixir mix 自定义任务
    elixir的mix比较灵活,同时也比较强大,很多时候我们可以自己定义一个任务,方便运行以及构建,不少三方框架会提供一些方便的cli,一般也会使用此方法比如ectoorm框架,以下是一个简单的自定义task学习参考开发目录位置这个实际上都f放那里可以,只是有一个简单的约定,建议放到lib/mix/......
  • 【C++】STL 容器 - STL 容器的值语意 ( 容器存储任意类型元素原理 | STL 容器元素可拷
    文章目录一、STL容器的值(Value)语意1、STL容器存储任意类型元素原理2、STL容器元素可拷贝原理3、STL容器元素类型需要满足的要求4、STL容器迭代器遍历二、代码示例-自定义可存放入STL容器的元素类1、代码示例2、执行结果一、STL容器的值(Value)语意1、STL......
  • 估计量评价与分类算法的对比
    1.背景介绍随着数据量的增加,人工智能和机器学习技术在各个领域的应用也不断扩大。估计量和分类算法是这些领域中最常见的技术之一。在这篇文章中,我们将讨论这两种算法的基本概念、原理、应用和优缺点,以及它们之间的区别和联系。估计量(Estimation)和分类(Classification)算法都是用于解......
  • 一款可实现个性化配置的低代码开发平台,打造完美自定义首页
    通常系统软件都会有首页展示,是用户首次打开系统软件时看到的页面,是用户对软件的第一印象。同时不同的软件类型和目标用户群体对首页的风格和内容会有所差异,JVS低代码平台就可以通过自定义页面引用外部站点来设置成首页,还可以直接在nacos中设置配置文件来切换首页,从而可以提高用户对......
  • 夜莺自定义告警模板
    !!大家好,我是乔克,一个爱折腾的运维工程,一个睡觉都被自己丑醒的云原生爱好者。作者:乔克公众号:运维开发故事博客:www.jokerbai.com预期目标Pastedimage20230906090309.png希望在告警通知里有以下数据:告知当前系统还有多少未处理的告警告知当前告警恢复时候的具体值告警通知里增加查......
  • Qt生成动态库和使用动态库
    一、动态库的生成第一步.新建项目——库——C++Library——点击选择按钮第二步.填写名称——新建路径——点击下一步按钮第三步:选择Buildsystem:默认的qmake即可——点击下一步按钮第四步:设置库的类型默认的SharedLibrary即可——设置Qt module选择需要的模块——其他也设置为......
  • STM32MP157D-DK1 Qt程序交叉编译与运行测试
    上篇文章介绍了STM32MP157D-DK1开发板Qt镜像的构建,通过在Ubuntu中重新编译带有Qt功能的系统来实现。本篇在上篇的基础上,继续搭建Qt的交叉编译环境,实现Qt程序在Ubuntu中编译,在STM32MP157板子中运行。1编译安装SDK在上篇编译系统镜像的基础上,继续编译和安装SDK。1.1编译SDK执行如下......
  • ant design vue 图片预览组件自定义样式
    这篇文章主要为大家介绍了ant design vue 图片预览组件自定义样式方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪−目录版本:场景:需求:版本:antdesignvue3.2.4场景:使用Image图片组件预览功能需求:自定义预览遮罩层及预览图片的样式;不得影响到其......
  • 安装MySQL数据库及QT添加数据库驱动连接使用
    1.下载官方地址MySQLCommunityserver8.2.0innovation:MySQL社区版的服务器软件,目前最新版本是8.2.0SelectVersion:选择你需要下载的版本号SelectOperatingSystem:选择操作系统,支持安装的操作系统如下Windows(x86,64bit),MSIInstaller(MSI=microsoftinstaller):推荐选择W......
  • Three.js——十三、自定义大小画布、UI交互按钮以及3D场景交互、渲染画布为文件(图片)
    画布全屏以及自定义大小画布<!--canvas元素默认是行内块元素--><divclass="model"style="background-color:#ff0000;"width="300"height="180"></div>画布随窗口变化//画布跟随窗口变化window.onresize=function(){constwidth......