Qt下载大文件



我正在尝试为我的应用程序创建一个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()信号和大文件兼容?

如果您正在使用writeReady(),您应该改为侦听readReady(!

不确定这是否有帮助,但是,1)file->close()应该在if(file->open()内部,否则关闭它没有意义,2)readAll()可能会返回一个空的QByteArray(),所以我会在将其发送到流之前测试内容,也会避免QDataStream,但只需使用:QByteArray data=reply->readAll(;文件->写入(数据)

QDataStream向QIODevice提供特定于Qt的二进制数据序列化,并用于流式处理的"两侧"(即,使用QDataStream序列化到QIODevice的数据意味着随后使用QDataStream读回处理,最好使用相同版本的二进制协议)。因此,QDataStream将信息添加到它写入的流中,以提供版本控制数据,确保QDataStream的未来版本向后兼容,这就是为什么在将数据写入文件时会看到额外的数据。

在您的情况下,您将希望放弃使用QDataStream,因为您正在将原始二进制数据写入文件。这可以通过删除上面的数据流类来实现,并用直接调用QIODevices的写方法来替换它:

if (file->write(reply->readAll()) == -1) {
   // some error occurred
}

您可能还想考虑只打开文件,而不是每次有可用数据时都打开它。我没有硬数字,但每次打开它几乎肯定会有不希望的开销,尤其是当你知道你会向它写入大量数据时。

最新更新