PDA

View Full Version : Proper file downloading?



matt4682
1st May 2014, 23:27
Currently in a project I'm working on I'm using a slightly modified version of this (http://stackoverflow.com/a/6341374) (emits fileSaved() and takes a save path) to download files like so:



QEventLoop imageLoop;
QDownloader *downloader = new QDownloader();
connect(downloader, SIGNAL(fileSaved()), &imageLoop, SLOT(quit()));

for(int i = 0; i < imageURLs.length(); i++) {
progressDialog->setValue((int)(100 * (double)i / imageURLs.length()));
progressDialog->setLabelText("Downloading image: " + QString::number(i + 1) + "/" + QString::number(imageURLs.length()));

if(progressDialog->wasCanceled())
break;

downloader->setFile(imageURLs.at(i), QDir::homePath() + "/images/" + imageNames.at(i) + ".jpg");
imageLoop.exec();
}


The program crashes sometimes doing this and I was wondering what I am doing wrong or what is a more common or appropriate way to accomplish this.

Thanks

ChrisW67
2nd May 2014, 00:48
Run your program in your debugger and when it crashes inspect the stack back trace to determine where, and usually why, it has crashed.

matt4682
2nd May 2014, 02:00
Run your program in your debugger and when it crashes inspect the stack back trace to determine where, and usually why, it has crashed.

It looks like it's crashing on



void QDownloader::onReadyRead()
{
file->write(reply->readAll());
}


So I added a quick check to isWritable() and it still end up crashing but file->isOpen() returns false.

Eventually I determined that the issue was that the finished() signal kept firing before the final readyRead() so the file would close.

I also ended up moving the



connect(manager,SIGNAL(finished(QNetworkReply*)),t his,SLOT(onFinished(QNetworkReply*)));


statement to the constructor because it was calling the slot an extra time for each file downloaded.

ChrisW67
2nd May 2014, 05:24
Looking at that code you should not need that connect() from the manager at all. You either connect to the QNetworkAccessManager::finished() signal or the QNetworkReply::finished() signal but not both. It's unlikely the reply's finished signal would come before the reply's last readyRead so I would use those.

matt4682
2nd May 2014, 11:45
Thanks a bunch, it's running flawlessly!