【发布时间】:2018-04-05 12:47:30
【问题描述】:
我想读取一个大数据,然后使用 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。Fail运行良好。
【问题讨论】:
-
我在
Qt中使用的文件是您提到的大小的 10 倍。话虽如此,这是来自本地磁盘。过去,我在 Windows 客户端上通过 samba 网络共享读取类似大小的文件(几百 MB)时遇到问题。在那种情况下,我不得不将阅读分成更小的块。 -
不要使用
readAll()。对于那些懒得思考如何将输入作为流处理的程序员来说,这只是一个快速的技巧。如果您真的非常需要随机访问整个文件,请考虑对其进行内存映射(如果原生mmap()便携性不足,您可以使用boost::interprocess)。 -
@JesperJuhl Buddy,我已经编辑了我的帖子。现在可以了吗?
-
您应该在 read() 调用中使用不同的缓冲区大小进行基准测试,以找出最佳性能的缓冲区。