<>QT中根据url下载实体文件
新建下载实体文件的类,实例化下载类对象便可调用下载类中的下载实体文件的函数。
代码实现:
QUrl url("下载实体文件的url地址"); QString path = url.toString();//url转QString //实例化下载类
download *loadFile = new download; loadFile.show();//可显示下载进程的界面 //调用开始下载函数
loadFile->startDownload(path); //其他下载到保存的路径等操作在download.cpp中完成
download.h
#ifndef DOWNLOAD_H #define DOWNLOAD_H #include <QWidget> #include<QPixmap>
#include<QPalette> #include<QBrush> #include<QMessageBox>
#include<QResizeEvent> #include<QDebug> #include <QUrl> #include <QtNetwork>
#include <QNetworkRequest> #include <QNetworkReply> #include
<QNetworkAccessManager> namespace Ui { class download; } enum Status {
requestHead=0, requestBody, }; class download : public QWidget { Q_OBJECT
public: explicit download(QWidget *parent = nullptr); ~download(); void
startDownload(const QString &url); void getCurrentFileSize(); void
stopDownLoad(); void addurl(QString url); void onDownloadProgress(qint64 cur,
qint64 total); private slots: void onFinishedRequest(); void onReadyRead();
void onError(QNetworkReply::NetworkError error); void on_pushButton_clicked();
private: Ui::download *ui; QNetworkAccessManager *m_netWorkManager;
QNetworkReply *m_reply; int m_fileSize; int m_statusCode; qint64
m_downLoadedBytes; qint64 m_currentLoadedBytes; QString m_fileName; QString
m_url; Status m_state; bool m_IsDownloading; QFile m_file; }; #endif //
DOWNLOAD_H
download.cpp
#include "download.h" #include "ui_download.h" download::download(QWidget
*parent) : QWidget(parent), ui(new Ui::download), //初始化
m_netWorkManager(nullptr), m_reply(nullptr), m_fileSize(0), m_statusCode(0),
m_downLoadedBytes(0), m_currentLoadedBytes(0), m_fileName(""), m_url(""),
m_IsDownloading(false) { ui->setupUi(this); m_netWorkManager = new
QNetworkAccessManager(); ui->progressBar->reset(); } download::~download() {
delete ui; } //开始下载 void download::startDownload(const QString &url) {
m_url=url; if(m_url.isEmpty()) return; if(!m_IsDownloading) {
//获取文件名(要根据实际的url判断) QStringList strlist = m_url.split("&"); for(int i=0;
i<strlist.size(); i++) { if(strlist.at(i).contains("fileName=")) { m_fileName =
strlist.at(i).split("=").at(1); } } qDebug()<<"fileName = "<<m_fileName;
//获取请求头 QNetworkRequest request; QUrl url = QUrl(m_url); request.setUrl(url);
m_reply = m_netWorkManager->head(request); m_state = requestHead;
getCurrentFileSize();
connect(m_reply,SIGNAL(finished()),this,SLOT(onFinishedRequest())); } } //结束请求
void download::onFinishedRequest() { if(m_reply==nullptr) return; if(m_state ==
requestHead) { m_fileSize = m_reply->rawHeader("Content-Length").toInt();
qDebug()<<"m_fileSize = "<<m_fileSize; //根据文件大小判断是否存在该文件
if(m_currentLoadedBytes == m_fileSize) { qDebug()<<"文件已经存在!";
QMessageBox::warning(this,"警告",m_fileName+"文件已经存在!"); return; } QNetworkRequest
request; request.setUrl(QUrl(m_url)); QEventLoop *loop = new QEventLoop;
connect(m_netWorkManager, SIGNAL(finished(QNetworkReply*)), loop,
SLOT(quit())); m_reply = m_netWorkManager->get(request); loop->exec(); //获取状态码
m_statusCode =
m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug()<<"statusCode="<<m_statusCode; m_state = requestBody; } QNetworkRequest
request; if(m_statusCode==200) { request.setUrl(QUrl(m_url)); } else
if(m_statusCode == 302) //存在转调url { //获取实际下载地址 QUrl realUrl =
m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
request.setUrl(realUrl); } else if(m_statusCode == 301) { QUrl realUrl =
m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
m_reply->deleteLater(); request.setUrl(realUrl); } else { return; } QString
downLoadSize = QString::number(m_fileSize); QString selectSize =
QString("bytes=%1-%2").arg(m_currentLoadedBytes).arg(downLoadSize);
request.setRawHeader("Range",selectSize.toLatin1()); m_reply =
m_netWorkManager->get(request);
connect(m_reply,SIGNAL(finished()),this,SLOT(onFinishedRequest()));
connect(m_reply,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
connect(m_reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(onError(QNetworkReply::NetworkError)));
} //准备读取 void download::onReadyRead() { if(m_reply==nullptr) return;
if(!m_file.isOpen()) { QString downLoadDirName = "保存路径"; //QString
downLoadDirName = QCoreApplication::applicationDirPath()+"/download";
qDebug()<<downLoadDirName; QDir downLoadDir(downLoadDirName);
if(!downLoadDir.exists()) {//判断路径是否存在,若不存在,自动创建
downLoadDir.mkdir(downLoadDirName); } m_file.setFileName(downLoadDirName +
m_fileName); m_file.open(QIODevice::WriteOnly|QIODevice::Append); }
m_file.write(m_reply->readAll()); m_downLoadedBytes =m_file.size();
onDownloadProgress(m_downLoadedBytes, m_fileSize);//显示下载进程 if(m_file.size() ==
m_fileSize) { qDebug()<<"download finished!"; stopDownLoad(); } } //停止下载 void
download::stopDownLoad() { if(m_reply == nullptr) return;
disconnect(m_reply,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
disconnect(m_reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(onError(QNetworkReply::NetworkError)));
disconnect(m_reply,SIGNAL(finished()),this,SLOT(onFinishedRequest()));
m_reply->abort(); m_reply->deleteLater(); m_file.close(); getCurrentFileSize();
m_IsDownloading = false; QMessageBox::information(this,"提示","下载完成!"); }
//获取当前文件大小 void download::getCurrentFileSize() { QFileInfo
fileInfo("保存路径"+m_fileName); if(fileInfo.exists()) { m_currentLoadedBytes =
fileInfo.size(); } else { m_currentLoadedBytes = 0; } } //界面化显示下载进程,可不用 void
download::onDownloadProgress(qint64 cur, qint64 total) { QString totalSize =
QString::number(total/(1024*1024)) + "M"; QString currentSize =
QString::number(cur/(1024*1024)) + "M";
ui->label->setText("Downloading."+currentSize +"/"+totalSize);
ui->progressBar->setMaximum(total); ui->progressBar->setValue(cur); }
//界面化显示url地址,可不用 void download::addurl(QString url) {
ui->lineEdit->setText(url); } //界面化显示按钮,可不用 void
download::on_pushButton_clicked() { startDownload(ui->lineEdit->text()); }
//下载错误提示 void download::onError(QNetworkReply::NetworkError error) {
Q_UNUSED(error); if(m_reply==nullptr) return;
qDebug()<<"error:"<<m_reply->errorString(); }