Download large with QNetworkreply :: readAll freezes for a few seconds

3

When using QNetworkreply::readAll to write data to a QFile , at the time the download arrives at the end, there is a fast freeze of 2 to 4 seconds and it also varies depending on the network or site I am downloading, to normal and the download ends.

It seems that the buffer read increases more than normal at the end

Here is an example code:

int main(int argc, char** argv)
{
    QCoreApplication a(argc, argv);

    QFile file("C:/exemplo/bigfile.7z");

    if(!file.open(QIODevice::WriteOnly)) {
        return 1;
    }

    QNetworkAccessManager manager;

    QNetworkRequest request(QUrl("http://localhost/bigfile.7z"));

    QNetworkReply *reply = manager.get(request);

    QObject::connect(reply, &QNetworkReply::readyRead, [&](){
        QTime time;
        time.start();

        QByteArray ba = reply->readAll();
        file.write(ba);

        int duration= time.elapsed();

        qDebug() << "read" << ba.size() << " bytes of data. (" << duration << " msecs)";
    });

    QObject::connect(reply, &QNetworkReply::finished, [&](){
        qDebug() << "finished!";
        a.quit();
    });

    return a.exec();
}

This problem occurs when I try to download large files like 300mb for example, see the result:

Note that at the end of the download (practically 99%), reply->readAll and write , takes 1617msecs and then 2741msecs, or almost 4 seconds, see that readAll on the last two calls returned much more data .

This causes a small crash in GUI applications (which use QWidget ).

    
asked by anonymous 05.11.2016 / 20:12

1 answer

1

I noticed that readyRead is high only at the end, maybe it is the application or the network that tries to advance the download process, this varies from network to network and according to the speed of the same, that is the problem can occur a time and another not.

In GUI applications it is this long recording time that causes the "locking" sensation for ~ 4 seconds.

What I decided was to limit buffer , for this I used QNetworkReply::setReadBufferSize , see result difference:

The reading was no more than 1048576 bytes, which took between 2 and 10 msecs to record, ie not spent half a second.

    
07.11.2016 / 19:22