我想读取大数据,然后使用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. 失败运行良好。
答案 0 :(得分:7)
将这两个文件作为QFiles打开。在一个循环中,read将固定数量的字节(比如4K)从输入文件放入一个数组中,然后将write该数组放入输出文件中。继续,直到你用完字节。
但是,如果您只想逐字复制文件,可以使用QFile::copy
答案 1 :(得分:2)
您可以使用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();
}
}
答案 2 :(得分:1)
要记住一件事:
使用read()
,您可以为当前读取的块指定最大大小(在示例中为3 * 1024字节),使用readAll()
指示程序一次读取整个文件。
在第一种情况下,您(重复地)将3072字节放在堆栈上,写入它们,一旦当前循环迭代结束,它们就会从堆栈中删除。在第二种情况下,您将整个文件推送到堆栈上。一次在堆栈上推600MB可能是您遇到性能问题的原因。如果你试图立即将6GB放在堆栈上,可能会耗尽内存/地址空间 - 导致程序崩溃。