Qt读取文件对比:每次获取自定义的长度和使用系统的API,耗时对比
2024-01-08 23:30:13
    		0. 前言
在编程过程中,经常遇到文件读写操作,太频繁了。每次也都写的不一样。
 突发奇想,想测试下几种不同的读取文件的效率。
 测试以下三种方式读取文件效率:
- 自定义读取文件耗时
- 使用QFile类API读取文件耗时
- 使用QTextStream类API读取文件耗时
在测试前,说一下使用到的知识点。
1. Qt读取文件
QFile类提供了一个读取和写入文件的接口。
 QFile是一个读写文本、二进制文件和资源的I/O设备。QFile可以单独使用,但更多是与QTextStream或QDataStream一起使用。
 QFile文件分隔符为’/‘,不分操作系统。不支持使用其他分隔符(例如’'),但可以使用"\\"。
 如:
QFile file("C:/User/Desktop/in.txt");
或
QFile file("C:\\User\\Desktop\\in.txt");
可以使用exists()检查文件是否存在,并使用remove()删除文件。(QFileInfo和QDir是文件操作相关类)
 文件用open()打开,用close()关闭,用flush()刷新。
 size()返回文件的大小。可以使用pos()获取当前文件位置,或者使用seek()移动到新的文件位置。如果到达文件的末尾,atEnd()返回true。
QTextStream类为读取和写入文本提供了方便的接口。
 QTextStream可以在QIODevice, QByteArray或QString上操作。使用QTextStream的流操作符,可以方便地读取和写入单词,行和数字。
以下是QFile和QTextStream读取文件示例
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);

 由此可以得出:
 还是使用QTextStream进行解析效率最高。
 但如果是自定义解析格式,就得用第一种实现方式了。
    			文章来源:https://blog.csdn.net/MrHHHHHH/article/details/135467892
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!