如何在 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::string
。 QString
更像是std::wstring
。并不是说这些是相同的 1:1 匹配,但将它们视为相似会有所帮助。
【讨论】:
以上是关于如何在 Qt 中从 txt 文件中加载大数据的主要内容,如果未能解决你的问题,请参考以下文章