使用QNetworkreply下载大文件:: readAll冻结几秒钟

时间:2016-11-05 20:56:22

标签: qt qwidget qtnetwork

我使用了像doc http://doc.qt.io/qt-4.8/qnetworkaccessmanager.html

这样的例子

我创建了一个startDownload

connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(startDownload(bool)));

startDownload(bool)我说了这个:

file = new QFile("C:/foo/bar/bigfile.7z");
file->open(QIODevice::WriteOnly);

QNetworkRequest request;
request.setUrl(QUrl("http://localhost/bigfile.7z"));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");

QNetworkReply *reply = manager->get(request);

connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
        this, SLOT(slotError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(sslErrors(QList<QSslError>)),
        this, SLOT(slotSslErrors(QList<QSslError>)));

slotReadyRead我说了这个:

file->write(reply->readAll());

但是当下载到达结束时,有一个小的冻结2秒然后恢复正常并且下载完成。如果我尝试传输的文件很大,则只会出现此问题。

2 个答案:

答案 0 :(得分:2)

这是预期的行为。 QIODevice::readAll()将阻止该线程,直到下载完成。根据磁盘速度和缓存策略,QFile::write()可能也会阻塞。如果文件足够大,readAll()方法也可能消耗相当多的RAM。

最简单的解决方案是使用read()代替readAll()以较小的块下载文件。

现在说,没有简单的方法可以找到完美的缓冲区大小来从网络读取并写入磁盘;它将取决于网络连接如何响应磁盘写入速度。

答案 1 :(得分:1)

尝试使用@Mike代码后,我注意到readyRead final中读取的数据远远高于前一个,这使得在文件中写入速度变慢:

without setReadBufferSize

最后两个读数是:

  1. 46080000字节 - 写入需要约1.6秒。
  2. 227323951字节 - 写入需要大约2.7秒。
  3.   

    它根据网络类型和速度而变化,允许缓冲区很好。

    在GUI应用程序中会产生一种&#34;冻结&#34;持续约4秒。

    对于使用QNetworkReply::setReadBufferSize的限制缓冲区,请参阅差异:

    with setReadBufferSize

    读数为1048576字节 - 写入需要2到10毫秒。