如何在 Qt 中从 txt 文件中加载大数据

Posted

技术标签:

【中文标题】如何在 Qt 中从 txt 文件中加载大数据【英文标题】:How to load large data from txt file in Qt 【发布时间】:2017-10-15 09:53:43 【问题描述】:

我需要尽快将一个包含 500 万个数据的 txt 文件(即字符串,只有一个单词,每个单词 9 个字符由换行符分隔。)加载到 QVector 中。代码现在工作得很好,但是,如果用户点击上传,应用程序需要 3-5 秒来加载此数据以进行进一步操作。我需要减少加载这些数据的时间。处理这个问题的正确方法是什么?我对 Qt/STL/Boost 没意见。不过我更喜欢Qt。我用于此任务的代码是 Qt 文档中建议的代码,即

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

QTextStream in(&file);
while (!in.atEnd()) 
    QString line = in.readLine();
    process_line(line);

【问题讨论】:

【参考方案1】:

试试这个:

我测试它并在 2.1 秒内读取文件。

我在阅读之前reserve矢量并使用QElapsedTimer获取阅读时间。

void MainWindow::readDataText()

    QString filePath = "F:\\Qt\\Big_File\\Big_File\\data.txt";
    QVector<qint64> *vector = new QVector<qint64>;
    vector->reserve(5000000);
    QElapsedTimer timer;
    QFile readFile(filePath);
    if(!readFile.open(QFile::ReadOnly | QFile::Text))
    
        // Can't Open File.
    
    else
    
        QByteArray data;
        timer.start();
        for (int var = 0; var < 5000000; ++var)
        
            vector->insert(var, (readFile.readLine()).toInt());
        
        qint64 time = timer.elapsed();
        ui->txtReadTimeText->setText(QString::number(time));
    
    readFile.close();

如果你的文件是二进制文件会更好。

另一种解决方案是使用readAll()函数并在116毫秒内读取文件,然后像这样处理(由'\n'分割)数据:

void MainWindow::readDataText()

    QString filePath = "D:\\ProjectTest\\ProjectTest\\data.txt";
    QByteArray data;
    data.reserve(5000000);

    QElapsedTimer timer;
    QFile readFile(filePath);
    if(!readFile.open(QFile::ReadOnly | QFile::Text))
    
        // Can't Open File.
    
    else
    
        timer.start();
        data = readFile.readAll();
        qint64 time = timer.elapsed();
        ui->txtReadTimeText->setText(QString::number(time));
    
    readFile.close();

【讨论】:

【参考方案2】:

您的示例代码实际上隐含地进行解码。它从文件中读取 8 位编码文本,并将其转换为 QString,它在内部使用 16 位 Unicode 编码。

如果你不使用QTextStream,而是直接使用普通的QFile,并使用readLine 方法读取它,那么你可能会获得很大的加速,它返回QByteArray,换句话说“原始"文件内容。这样做的目的是避免为整个文件内容创建QString 对象。

如果您有 500 万行,那么如果您将它们存储在内存中 QByteArray 而不是 QString 中,您还将获得显着的内存占用节省。仅当您实际要在 GUI 中显示文本时才转换为 QString


注意:注意文本编码!任何文件中的任何文本都总是编码,即使说英语的人可能没有意识到这一点。最直接的编码是 7-bit ASCII,很多纯英文文本其实就是这个,而且几乎所有的编码包括 UTF-8 实际上都是 7-bit ASCII 的超集,所以 7-bit ASCII 文件几乎可以使用任何编码加载.但是对于多语言文本,您需要知道文件使用什么编码,否则您将得到错误的重音字符和其他特殊字符,例如 ÄÅÁÀÃ。 UTF8 是唯一可以存储“一切”的编码,其他编码如 Latin1 是为特定语言家族设计的。

注意 2:QByteArray 在大多数情况下实际上对应于std::stringQString 更像是std::wstring。并不是说这些是相同的 1:1 匹配,但将它们视为相似会有所帮助。

【讨论】:

以上是关于如何在 Qt 中从 txt 文件中加载大数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Google BigQuery 中加载大文本文件

如何在 python 中加载大的 .mat 文件?

如何在 MATLAB 中加载大文件(~150MB)?

在 Pandas 数据框中加载大表时,如何避免 EC2 中的内存错误?

如何在unity3d中加载大工程模型

如何使用角度6的分页,过滤,排序功能在表组件中加载大数据