• QT实现,通过URL下载文件的接口实现


    今天来把坑填上。 
    具体就是提供一个URL,并通过这个URL下载文件。 
    MyDownloader.h: 
    #ifndef MYDOWNLOADER_H 
    #define MYDOWNLOADER_H 
    class MyDownloader :public QObject 

    Q_OBJECT

    public:

    //构造函数,要求下载地址,保存位置,进度条(可选)
    MyDownloader();
    ~MyDownloader();
    
    // 设置要下载的url和文件名
    void setData(QUrl url, QString pathtoSave);
    //开始下载
    void getFile();
    void startRequest(QUrl url);
    //发生的错误代码
    int lastError();
    //返回是否有错误发生
    bool errorValid();
    //返回是否下载中
    bool isRunning();
    //返回是否下载完成
    bool isFinished();
    //返回所下载文件的版本号
    QString getDownloadVersionCode();
    //返回所下载文件的名字(带扩展名)
    QString getFileName();
    void cancel();
    

    private:

    //=====状态变量=====
    bool bisFinished;   //下载是否完成
    bool bisRunning;    //下载是否进行中
    bool bisError;      //是否有错误发生
    int errorCode;      //错误代码
    int allBits = 0;    //文件大小
    bool httpRequestAborted;
    
    //=====对象声明=====
    QFile *downloadFile;                //保存目标文件指针
    QUrl downloadUrl;                   //下载地址Url
    QString savePath;                   //文件存放路径
    QString versionCode = "";           //所下载的文件版本号
    QString fileName = "";              //所下载文件名
    QNetworkReply *downloadReply;       //网络应答指针
    QNetworkAccessManager downloadmanager;     //网络连接主类指针
    

    signals:

    //当错误发生时向外抛出错误信息
    void error(QNetworkReply::NetworkError);
    //抛出下载进度(更新进度条)
    void updateProgress(qint64, qint64);
    //下载结果 0成功 其他失败
    void downloadResult(int retCode);
    

    private slots:

    //准备下载,读取数据
    void downloadReadyRead();
    //下载完成
    void downloadFinished();
    //下载过程中发生错误
    void downloadError(QNetworkReply::NetworkError);
    //下载过程进度条
    void downloadProgress(qint64, qint64);
    

    };

    #endif// MYDOWNLOADER_H

    具体实现: 
    MyDownloader.cpp:

    MyDownloader::MyDownloader() 
    {

    downloadFile = NULL;
    downloadReply = NULL;
    bisFinished = false;
    

    }

    MyDownloader::~MyDownloader() 
    {

    cancel();
    

    }

    void MyDownloader::setData(QUrl url, QString pathtoSave) 
    {

    downloadUrl = url;
    savePath = pathtoSave;
    

    }

    void MyDownloader::getFile() 
    {

    if (savePath.isEmpty() || downloadUrl.isEmpty())
    {
        return;
    }
    if (downloadFile)
    {
        return;
    }
    bisFinished = false;
    downloadFile = new QFile(savePath);
    
    if (!downloadFile->open(QIODevice::WriteOnly))
    {
        delete downloadFile;
        downloadFile = 0;
        return;
    }
    allBits = downloadFile->size();
    httpRequestAborted = false;
    //尝试获取文件
    startRequest(downloadUrl);
    //事件循环,防止在下载没完成前结束对象
    

    }

    void MyDownloader::startRequest(QUrl url) 
    {

    QNetworkRequest req(url);
    if (allBits)
    {
        //QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(allBits) + "-";// + QByteArray::number(already + cUpdateChunk() - 1); 
        //req.setRawHeader("Range", rangeHeaderValue);
        //req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
        //req.setRawHeader("RANGE", tr("bytes=%1-").arg(allBits).toUtf8());//
    }
    downloadReply = downloadmanager.get(req);
    //连接信号与槽
    if (downloadReply)
    {
        connect(downloadReply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
        connect(downloadReply, SIGNAL(finished()), this, SLOT(downloadFinished()));
        //connect(downloadReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
    }
    

    }

    QString MyDownloader::getDownloadVersionCode() 
    {

    return versionCode;
    

    }

    QString MyDownloader::getFileName() 
    {

    return fileName;
    

    }

    void MyDownloader::downloadReadyRead() 
    {

    //如果文件可以访问,下载
    if (downloadFile)
        downloadFile->write(downloadReply->readAll());
    

    }

    void MyDownloader::downloadProgress(qint64 bytesRead, qint64 totalBytes) 

    }

    void MyDownloader::cancel() 
    {

    if (downloadFile)
    {
        downloadFile->close();
        delete downloadFile;
        downloadFile = NULL;
    }
    if (downloadReply)
    {
        downloadReply->deleteLater();
        downloadReply = NULL;
    }
    

    }

    void MyDownloader::downloadFinished() 
    {

    if (httpRequestAborted)
    {
        cancel();
        return;
    }
    downloadFile->flush();
    downloadFile->close();
    
    QVariant redirectionTarget = downloadReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (downloadReply->error())
    {//299提示RANGE错误
        DEBUG_LOG(qsl("downloadReply error code:") + QString::number(downloadReply->error()));
        //downloadFile->remove();
        //emit downloadResult(-1);
    }
    else if (!redirectionTarget.isNull())
    {
        QUrl newUrl = downloadUrl.resolved(redirectionTarget.toUrl());
        {
            downloadUrl = newUrl;
            downloadReply->deleteLater();
            downloadFile->open(QIODevice::WriteOnly);
            downloadFile->resize(0); allBits = 0;
            startRequest(downloadUrl);
            return;
        }
    }
    else
    {
        QString fileName = QFileInfo(downloadUrl.path()).fileName();
        delete downloadFile;
        downloadFile = 0;
        bisFinished = true;
        emit downloadResult(0);
    }
    downloadReply->deleteLater();
    downloadReply = 0;
    if (downloadFile)
    {
        delete downloadFile;
        downloadFile = 0;
    }
    

    }

    void MyDownloader::downloadError(QNetworkReply::NetworkError errorcode) 
    {

    emit downloadResult(-1);
    

    }

    bool MyDownloader::errorValid() 
    {

    return false;
    

    }

    int MyDownloader::lastError() 
    {

    return 0;
    

    }

    bool MyDownloader::isRunning() 
    {

    return false;
    

    }

    bool MyDownloader::isFinished() 
    {

    return bisFinished;
    


    有些方法没有具体实现,(现在没有用到),是否有错误发生,判断是否下载中,是否下载完成,等 
    ////////////////////////////////////////////////////////////////////// 
    使用: 
    mian.cpp 
    void main() 
    { 
    MyDownloader m_downLoder; 
    m_downLoder.setData(QUrl(m_si.custInfo.szLogoLargeUrl.c_str()), bigLogoPath); 
    m_downLoder.cancel(); 
    m_downLoder.getFile(); 
    } 
    ////////////////////////////////////////////////////////////////////////////////////// 
    全文完

    http://blog.csdn.net/u011915578/article/details/46592963

  • 相关阅读:
    如何更改SQL Server2008默认数据库的存储路径
    虚拟内存页面文件pagefile.sys(棉文件)改变存放位置
    Redis热点数据高频访问问题以及解决方案
    gc日志收集和分析
    oauth2中client_id_to_access数据膨胀问题
    Redis慢查询日志
    24个Jvm面试题总结及答案
    springboot-使用assembly进行项目打包
    volatile关键字解读
    redis的zset结构跳表
  • 原文地址:https://www.cnblogs.com/findumars/p/5068079.html
Copyright © 2020-2023  润新知