qt通过http请求下载文件(支持断点续传)
点击查看代码
void Download::on_downloadBtn_clicked()
{
if(file.exists())
{
if(isDownload==false)
{
ui->downloadBtn->setText("暂停");
isDownload=true;
if(isDisconnect)
{
startDownload(ui->urlEdit->document()->toPlainText());
}
}
else
{
ui->downloadBtn->setText("下载");
isDownload=false;
isDisconnect=true;
disconnect(reply,0,0,0);//断开与reply相关的所有连接
reply->abort();
reply->deleteLater();
reply=NULL;
}
}
if(file.exists()&&!isDownLoadError)
{
return;
}
QString url=ui->urlEdit->document()->toPlainText();
int index=url.lastIndexOf('/');
QString filename=url.mid(index+1);
QString filePath=QFileDialog::getExistingDirectory(NULL,"保存路径","./");
file.setFileName(filePath+'/'+filename);
if(!file.open(QIODevice::ReadWrite|QIODevice::Append))
{
receivedBytes=file.size();
QMessageBox::information(NULL,"info","open file fail");
return;
}
{
ui->downloadBtn->setText("暂停");
isDownload=true;
isDownLoadError=false;
}
startDownload(url);
}
void Download::startDownload(QString url)
{
QNetworkRequest request;
request.setUrl(QUrl(url));
//支持断点续传
QString strRange = QString("bytes=%1-").arg(receivedBytes);
request.setRawHeader("Range", strRange.toUtf8());
reply=manager->get(request);
connect(reply,&QNetworkReply::readyRead,this,&Download::dealData);
connect(reply,&QNetworkReply::finished,[this]()
{
reply->deleteLater();
if(!isDownLoadError)
{
ui->processImg->setPixmap(QPixmap(":/resources/progress/finished.png"));
ui->downloadBtn->setEnabled(false);
ui->downloadBtn->setText("完成");
}
file.close();
}
);
connect(reply,&QNetworkReply::downloadProgress,this,&Download::downloadProcess);
connect(reply,QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),this,&Download::downloadError);
}
void Download::dealData()
{
QNetworkReply*reply=dynamic_cast<QNetworkReply*>(sender());
file.write(reply->readAll());
receivedBytes=file.size();
}
void Download::downloadProcess(qint64 received, qint64 total)
{
if(firstDownload)
{
/*
* 把第一次下载时的文件长度(即整个文件的大小)保存起来
* 因为断点续传total会越来越小
*/
fileSize=QString::number(total);
firstDownload=false;
}
/*
* 之所以不用函数提供的两个参数(received、total),
* 是因为搞了半天那个进度条显示不正确,故采用此法
* 如果你有更好的办法,博客留言。。。
*/
ui->progressBar->setValue(receivedBytes);
ui->progressBar->setMaximum(fileSize.toInt());
}
演示效果:
参考链接:
http://www.suoniao.com/topic/5f3d7b8470fe9927be5bf408
https://blog.csdn.net/GoForwardToStep/article/details/52704464
https://blog.csdn.net/u013015629/article/details/111240513
https://blog.csdn.net/JimBraddock/article/details/84170461
源码链接:
链接:https://pan.baidu.com/s/1EGjiWr0UfoNcCBfLQiqvCQ
提取码:wscq
(代码如有问题,求指正。。。)