我正在尝试为我的应用程序创建一个FileDownloader类,它与下载大文件兼容,以避免在下载过程中使用大量内存。我编写了以下函数,使用QNetworkReply的readyRead()信号在下载期间写出文件:
void FileDownloader::writeReady(){
if(file->open(QIODevice::ReadWrite | QIODevice::Append)){
QDataStream fout(file);
fout << reply->readAll();
} else{
qDebug(file->errorString().toLatin1());
}
file->close();
}
这个问题是它没有写文件应该如何,文件被破坏了。但是,如果我使用finished()信号而不是readyRead()信号,它会完美地写出文件(它有一个加4字节大小的错误,但我可以打开文件并完全读取所有内容)。
如何使其与readyRead()信号和大文件兼容?
答案 0 :(得分:2)
你正在使用writeReady(),你应该监听readReady()!
不确定这是否有帮助,但是,1)file-&gt; close()应该在if(file-&gt; open()内部,否则它在关闭它时没有任何意义,也是2)readAll()可能会返回一个空的QByteArray(),所以我会在将内容发送到流之前对其进行测试,同时也避免使用QDataStream,但只需使用:QByteArray data = reply-&gt; readAll();文件 - →写(数据)
答案 1 :(得分:0)
QDataStream为QIODevice提供特定于Qt的二进制数据序列化,并且意图用于流处理的“双方”(即,使用QDataStream序列化到QIODevice的数据随后将被读回到使用QDataStream的进程,最好使用相同版本的二进制协议)。因此,QDataStream将信息添加到它所写的流中,以便提供版本控制数据,确保QDataStream的未来版本向后兼容,这就是为什么在将数据写入文件时看到额外数据的原因。
在您的情况下,您将要放弃使用QDataStream,因为您正在将原始二进制数据写入文件。这可以通过删除上面的数据流类来实现,并用直接调用QIODevice的write方法替换它:
if (file->write(reply->readAll()) == -1) {
// some error occurred
}
您可能还想考虑将文件保持打开状态,而不是每次有可用数据时打开它。我没有硬数字,但每次打开它几乎肯定是不受欢迎的开销,特别是当你知道你将要写入大量数据时。