QT中根据url下载实体文件

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


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唯时

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值