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();
}