QT:如何使用QT复制大数据

Qt: How can I copy a big data using QT?

本文关键字:QT 数据 复制 何使用      更新时间:2023-10-16

我想读一个大数据,然后使用qt写入新文件。

我试图阅读一个大文件。大文件只有一行。我用readAll()readLine()进行测试。

如果数据文件约为600MB,我的代码可以运行,尽管它很慢。

如果数据文件约为6GB,我的代码将失败。

您能给我一些建议吗?

更新
我的测试代码如下:

#include <QApplication>
#include <QFile>
#include <QTextStream>
#include <QTime>
#include <QDebug>
#define qcout qDebug()
void testFile07()
{
    QFile inFile("../03_testFile/file/bigdata03.txt");
    if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qcout << inFile.errorString();
        return ;
    }
    QFile outFile("../bigdata-read-02.txt");
    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;
    QTime time1, time2;
    time1 = QTime::currentTime();
    while(!inFile.atEnd())
    {
        QByteArray arr = inFile.read(3*1024);
        outFile.write(arr);
    }
    time2 = QTime::currentTime();
    qcout << time1.msecsTo(time2);
}
void testFile08()
{
    QFile inFile("../03_testFile/file/bigdata03.txt");
    if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))
        return;
    QFile outFile("../bigdata-readall-02.txt");
    if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return;
    QTime time1, time2, time3;
    time1 = QTime::currentTime();
    QByteArray arr = inFile.readAll();
    qcout << arr.size();
    time3 = QTime::currentTime();
    outFile.write(inFile.readAll());
    time2 = QTime::currentTime();
    qcout << time1.msecsTo(time2);
}
int main(int argc, char *argv[])
{
    testFile07();
    testFile08();
    return 0;
}

测试后,我分享了我的经验。

  • read()readAll()似乎很快;实际上, read()略快。
  • 真正的区别是写作。

文件的大小为600mb:
使用read函数,读取和写入有关 2.1s 的文件成本, 875ms 用于阅读
使用readAll函数,读取和写入有关 10s 的文件成本, 907ms 用于阅读

文件的大小为6GB:
使用read函数,读取有关 162S 的文件成本, 58S 用于阅读
使用readAll函数,获取错误的答案0。失败运行良好。

将两个文件打开为qfiles。在循环中,将固定数量的字节(例如4K(读取到输入文件中的数组中,然后将该数组写入输出文件中。继续直到您用完字节。

但是,如果您只想逐字复制文件,则可以使用qfile ::复制

您可以使用QFile::map并将指针使用映射的内存以单拍为目标文件:

void copymappedfile(QString in_filename, QString out_filename)
{
    QFile in_file(in_filename);
    if(in_file.open(QFile::ReadOnly))
    {
        QFile out_file(out_filename);
        if(out_file.open(QFile::WriteOnly))
        {
            const qint64 filesize = in_file.size();
            uchar * mem = in_file.map(0, filesize, QFileDevice::MapPrivateOption);
            out_file.write(reinterpret_cast<const char *>(mem) , filesize);
            in_file.unmap(mem);
            out_file.close();
        }
        in_file.close();
    }
}

要牢记的一件事:使用read(),您为当前读取块(在您的示例3*1024字节中(指定了最大大小,使用readAll(),您告诉程序一次读取整个文件。

在第一种情况下,您(反复(将3072字节放在堆栈上,写下它们,一旦当前环路迭代结束,它们就将其从堆栈中删除。在第二种情况下,您将整个文件推在堆栈上。立即将600MB推到堆栈上可能是您的性能问题的原因。如果您尝试立即将6GB放在堆栈上,则可能只用尽内存/地址空间 - 导致程序崩溃。