Qt 案例 使用QNetworkReply或者URLDownloadToFile 下载http、https资源到本地路径

编程入门 行业动态 更新时间:2024-10-25 11:28:32

Qt 案例 使用QNetworkReply或者URLDownloadToFile 下载http、https资源到本地<a href=https://www.elefans.com/category/jswz/34/1771438.html style=路径"/>

Qt 案例 使用QNetworkReply或者URLDownloadToFile 下载http、https资源到本地路径

Qt 使用QNetworkReply或者URLDownloadToFile两种不同方式下载http、https链接资源文件,并且获取下载进度。

目录

    • 一、 使用 URLDownloadToFile 下载
    • 二、 使用 QNetworkReply 下载
    • 三、 打包好的可执行程序示例下载
    • 四、 会员或订阅专栏下载源码

一、 使用 URLDownloadToFile 下载

使用【 URLDownloadToFile 】下载数据,只需调用函数,如果需要显示进度信息也只需要继承【IBindStatusCallback】类,通过重写OnProgress方法就能获取到及时进度:
头文件调用:

	#include <iostream>#include <Urlmon.h>// 下面这个也是#pragma comment(lib, "Urlmon.lib")// HRESULT URLDownloadToFile(//         LPUNKNOWN            pCaller,//         LPCTSTR              szURL,//         LPCTSTR              szFileName,//_Reserved_ DWORD                dwReserved,//         LPBINDSTATUSCALLBACK lpfnCB//);

调用:

    HRESULT ret =URLDownloadToFile(nullptr,_httpurl,_filepath,0,(LPBINDSTATUSCALLBACK)this);if (ret != S_OK)return false; // 下载失败

继承IBindStatusCallback主要需要实现以下方法,其中通过重写OnProgress方法获取到下载进度,通过返回S_OKE_ABORT判断是否继续下载文件:

class DOWNFILES:public QObject,public IBindStatusCallback
{HRESULT __stdcall QueryInterface(const IID &, void **) { return E_NOINTERFACE; }ULONG STDMETHODCALLTYPE AddRef(void) { return 1; }ULONG STDMETHODCALLTYPE Release(void) { return 1; }HRESULT STDMETHODCALLTYPE OnStartBinding(DWORD dwReserved, IBinding *pib) { return E_NOTIMPL; }virtual HRESULT STDMETHODCALLTYPE GetPriority(LONG *pnPriority) { return E_NOTIMPL; }virtual HRESULT STDMETHODCALLTYPE OnLowResource(DWORD reserved){ return S_OK; }virtual HRESULT STDMETHODCALLTYPE OnStopBinding(HRESULT hresult, LPCWSTR szError) { return E_NOTIMPL; }virtual HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD *grfBINDF, BINDINFO *pbindinfo) { return E_NOTIMPL; }HRESULT STDMETHODCALLTYPE OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed){ return E_NOTIMPL; }virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(REFIID riid, IUnknown *punk) { return E_NOTIMPL; }//    virtual HRESULT __stdcall OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)//    { if (ulProgressMax != 0) { double *percentage = new double(ulProgress * 1.0 / ulProgressMax * 100); //将percentage 发送给显示 delete percentage; } return S_OK;///进度HRESULT OnProgress( unsigned long ulProgress, unsigned long ulProgressMax,  unsigned long ulStatusCode, LPCWSTR  szStatusText) ;//{if(!THREAD_IS_SHOULD_QUIT){ return S_OK;} else {return E_ABORT;}}
};

注意: 使用URLDownloadToFile 下载数据时会在
【(参考路径)C:\Users\admin\AppData\Local\Microsoft\Windows\INetCache\IE】目录下生成缓存文件,如果是小文件影响不大,如果超过1G,系统盘很容易就没有使用空间。
也可以使用 DeleteUrlCacheEntry(URL链接) 或删除参考路径下的文件,但可能有其他问题
不建议使用这种方式下载。

二、 使用 QNetworkReply 下载

使用【QNetworkReply】下载数据,主要通过readyReaddownloadProgress信号保存数据和获取进度。如果是https链接还需要下载QSslSocket相关库。
pro头添加:

QT += network

URL下载资源数据校验参考:
可通过修改RawHeader的Range参数实现下载的断点继续下载功能。
通过返回的Last-Modified参考是否是最新文件,
通过返回的Content-Range获取文件大小。
添加QNetworkRequest 的重定向防止部分链接是跳转Https资源

#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>//! url 
//! filesize 获取文件大小
//! outime 链接超时时间
bool QTDOWNFILES::urlData_Validation(QString url,quint64& filesize,int outime)
{bool IsSuccess=false;qDebug()<<"[url] 数据效验:";QNetworkRequest request;request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);   //启动重定向qDebug()<<"[urlData_Validation] "<<url;///获取前500个字节效验文件是否过期request.setRawHeader("Range","bytes=0-499");request.setUrl(QUrl(url));//超时时间QTimer * out_timer = new QTimer();QEventLoop eventLoop;QNetworkAccessManager* manager=new QNetworkAccessManager();QNetworkReply *reply =manager->get(request);///线程超时QObject::connect(out_timer,&QTimer::timeout,reply,&QNetworkReply::abort,Qt::UniqueConnection);///只需要加载一次QObject::connect(reply, SIGNAL(readyRead()),&eventLoop, SLOT(quit()));out_timer->start(outime);eventLoop.exec(QEventLoop::ExcludeUserInputEvents);out_timer->stop();if(reply->error() != QNetworkReply::NoError){IsSuccess=false;}if(reply->hasRawHeader("Content-Range")){QVariant contentrange = reply->rawHeader("Content-Range");qDebug()<<"[Content-Range] "<<contentrange;QString size=contentrange.toString().mid((0,contentrange.toString().indexOf("/")+1));qDebug()<<"Size : "<<size;filesize=size.toLongLong();IsSuccess=true;}//    if(reply->hasRawHeader("Last-Modified"))//    {//        QVariant contentrange = reply->rawHeader("Last-Modified");//        QString LastModified=contentrange.toString();//        qDebug()<<"LastModified : "<<LastModified;//    }manager->clearConnectionCache();manager->clearAccessCache();reply->abort();reply->close();return IsSuccess;
}

绑定readyRead信号获取数据,和获取进度:

void QTDOWNFILES::WriteFileData()
{if(reply!=nullptr && file!=nullptr){//file 打开的QFILE类型文件QByteArray temparray= reply->readAll();if(temparray.length()>0)file->write(temparray);temparray.clear();}
}void QTDOWNFILES::HaveFulfilled(qint64 bytesRead,qint64 totalBytes)
{emit ToFulfilled(bytesRead,totalBytes);
}

1.注意: 使用QNetworkReply 下载时为了防止界面卡顿而使用多线程时,可以将QNetworkReply 的方法实现放入QOBJECT类中,在使用一个线程类来调用QOBJECT类中的方法,这样就避免了写入文件线程不同步的问题。也避免使用写锁。
2.SSL问题: HTTPS资源文件需要使用SSL库。
否则出现异常提示:qtwork.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
参考链接:
1.Qt 解决qtwork.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed问题
2.解决qtwork.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

三、 打包好的可执行程序示例下载

详见文章绑定资源;

四、 会员或订阅专栏下载源码

Qt开发项目案例-以及部分示例的源码下载链接

更多推荐

Qt 案例 使用QNetworkReply或者URLDownloadToFile 下载http、https资源到本地路径

本文发布于:2023-12-03 23:43:42,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1659081.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:路径   案例   资源   QNetworkReply   Qt

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!