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

news2024/12/28 13:09:06

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库。
否则出现异常提示:qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
参考链接:
1.Qt 解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed问题
2.解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

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

详见文章绑定资源;
在这里插入图片描述

在这里插入图片描述

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1126889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

USB协议学习(二)设备枚举过程分析

USB协议学习&#xff08;二&#xff09;设备枚举过程分析 笔者来聊聊设备枚举过程分析. 这里写自定义目录标题 USB协议学习&#xff08;二&#xff09;设备枚举过程分析USB设备运行过程USB设备枚举USB设备通信构成USB设备请求USB枚举过程分析如何改变文本的样式插入链接与图片如…

【算法训练-动态规划 二】【线性DP问题】最长递增子序列

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【动态规划】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

跨境电商:经济合作新引擎,技术赋能新亮点

随着数字化浪潮席卷全球&#xff0c;跨境电商正蓬勃发展&#xff0c;成为中国外贸高质量发展的新引擎。中国的跨境电商行业在"买全球、卖全球"方面正经历着显著的增长&#xff0c;延展出新的商业生态&#xff0c;以技术创新和国际合作为支撑&#xff0c;促进了中国制…

Linux中的shell外壳与权限(包含目录文件的权限,粘滞位的来龙去脉)

Linux中的shell外壳与权限[包含目录文件的权限,粘滞位的来龙去脉] 一.shell外壳的理解1.为什么需要有shell外壳的存在?2.什么是shell外壳?3.shell外壳的运行原理是什么?4.shell和bash的关系 二.Linux中的用户权限1.用户分类与身份切换1.用户分类2.root用户切换为普通用户1.s…

操作系统学习笔记7-IO管理

文章目录 1、IO管理学什么(学习逻辑图)2、IO管理硬件知识-IO设备的分类(硬件分类)3、IO管理硬件知识-IO控制方式的发展过程4、IO管理硬件知识-IO控制方式-程序直接控制方式5、IO管理硬件知识-IO控制方式-中断控制方式6、IO管理硬件知识-IO控制方式-DMA控制方式7、IO管理硬件知识…

JSX 样式处理

学习目标&#xff1a; 能够在 JSX 中实现 CSS 样式处理  1. 行内样式 实现&#xff1a; 在元素身上绑定一个 style 样式   - 行内样式 style function APP(){return (<div className"App"><div style{{color:red,fontSize:10px}}>this is div</d…

Swagger基本使用

文章目录 1. 接口文档2. Open API3. Swagger 简介4. Springfox5. Swagger 基本用法6. Swagger-UI使用7. Swagger配置 1. 接口文档 接口文档对于前后端开发人员都十分重要。尤其近几年流行前后端分离后接口文档又变成重中之重。接口文档固然重要&#xff0c;但是由于项目周期等…

MySQL数据同步到达梦数据库

1.服务器配置 达梦数据库的初始状态是不兼容其他任何数据库模式的&#xff0c;所以必须先设置系统的兼容性&#xff0c;从安装路径的tool文件夹中打开console工具&#xff08;DM控制台工具&#xff09;&#xff0c;设置兼容MySQL。 2.创建用户&#xff08;需要分配权限的操作&…

K8s 之 Helm 部署 MySQL 5.7

Author&#xff1a;rab 目录 一、环境二、部署2.1 安装 NFS2.2 安装 Helm2.3 安装 MySQL2.3.1 创建 Namespace2.3.2 创建 PV2.3.3 配置 MySQL2.3.4 部署 MySQL 2.4 MySQL 可用性验证 小结 一、环境 # K8s版本 v1.23.6# Docker版本 v20.10.20# Helm版本 v3.10.3# NFS v4说明&am…

建筑能源管理(6)——建筑能源监管

中国建筑(公共机构)能耗的总量逐年上升&#xff0c;在能源总消费量中所占的比例已从20世纪70年代末的10%&#xff0c;上升到近年的超过30%。2006年&#xff0c;《中华人民共和国国民经济和社会发展第十一个五年规划纲要》提出了“十一五”期间单位国内生产总值能耗降低20%左右&…

SocketBase类库

SocketBase类库主要是方便创建Socket客户端和Socket服务端的基础实现。 抽象基类&#xff1a;主要实现创建Socket public abstract class NetworkBase{} 通用基类&#xff1a;指定了消息的解析规则&#xff0c;指定了数据转换的规则 的基本实现 /// <summary>/// 支持长…

Flume基本使用--mysql数据输出

MySQL数据输出 在MySQL中建立数据库school&#xff0c;在数据库中建立表student。SQL语句如下&#xff1a; create database school; use school; create table student(id int not null,name varchar(40),age int,grade int,primary key(id) ); 请使用Flume实时捕…

SQL sever中的函数(基础)

目录 一、聚合函数 1.1聚合函数概述 1.2SUM(求和)函数 1.3AVG(平均值)函数 1.4MIN(最小值)函数 1.5MAX(最大值)函数 1.6COUNT(统计)函数 1.6.1COUNT函数用法分类 1.6.2COUNT函数用法示例 1.7DISTINCT(取不重复记录)函数 1.8查询重复记录 二、数学函数 2.1数学函数…

【Java小知识点】类加载器的区别

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理Java类加载器的区别&#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&#x1faf…

TDengine(taos)数据库导出历史数据

业务需求&#xff1a;导出某个站点的累计充电量&#xff0c;累计放电量&#xff0c;光伏总放电量&#xff0c;进线总功率的所有数据‘ 1、登录taos&#xff0c;使用存数据的库&#xff1b; 提示Database changed&#xff1b;即为使用成功&#xff1b; 2、找到你想要导出的字段…

USGS MODIS 蒸散量数据集

USGS MODIS 蒸散量 这里提供的蒸散量 (ET) 数据集是遥感技术的结果&#xff0c;主要利用 MODIS 热图像和全球天气数据集。该数据集对应于 Climate Engine 使用的全球 ET 产品的第 5 版。它为 2003 年至 2023 年期间的 ET 时空动态提供了宝贵的见解。该数据集的基石是可操作的简…

【go-zero】go-zero 脚手架 simple-admin 开篇:安装 了解 goctls

一、什么是goctls 1、github地址 官方链接: goctls链接:https://github.com/suyuan32/goctls 官方视频教程: SimpleAdmin环境配置-工具安装 2、goctls说明 二、安装 goctls 1、使用go install 推荐使用 go install 进行安装 我个人使用的是mac的zsh ,之前是git clone的源…

网络通信和tcp协议

一、计算机网络架构模型 1、OSI七层模型 2、TCP/IP模型 3、TCP/IP协议族 无论是什么网络模型&#xff0c;都是为上一层提供服务&#xff0c;抽象层建立在低一层提供的服务上&#xff0c;每层都对应不同的协议 4、地址和端口号 1&#xff09;MAC地址 MAC 地址共 48 位&#…

深入探究Java内存模型

文章目录 &#x1f31f; Java虚拟机内存模型&#x1f34a; 一、方法区&#x1f34a; 二、堆&#x1f389; 堆的基本概念&#x1f389; 堆的结构&#x1f4dd; 新生代&#x1f4dd; 老年代 &#x1f389; 堆的分配策略&#x1f4dd; 对象优先分配&#x1f4dd; 空间优先分配 &am…

数聚携手永达汽车集团强势入选爱分析《商业智能实践案例》

近日&#xff0c;国内知名数字化市场研究咨询机构爱分析发布《2023爱分析商业智能最佳实践案例》&#xff0c;此评选活动面向落地商业智能的各行企业和商业智能厂商&#xff0c;以第三方专业视角深入调研&#xff0c;评选出具有参考价值的创新案例。永达汽车集团与数聚股份合作…