热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

libcurl下载文件并实现进度条

昨天使用了windowsapi实现了下载文件以及显示下载进度:Windows客户端开发–URLDownloadToFile下载文件进度条今天就来说一使用libcu

昨天使用了windows api实现了下载文件以及显示下载进度:

Windows客户端开发–URLDownloadToFile下载文件进度条

今天就来说一使用libcurl实现http下载,并实现进度条。

简单介绍libcurl:
官网:
https://curl.haxx.se/
libcurl主要功能就是用不同的协议连接和沟通不同的服务器~也就是相当封装了的sockPHP 支持libcurl(允许你用不同的协议连接和沟通不同的服务器)。, libcurl当前支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传(当然你也可以使用PHP的ftp扩展), HTTP基本表单上传,代理,COOKIEs,和用户认证。

使用libcurl:

文档:
https://curl.haxx.se/libcurl/c/libcurl-tutorial.html

For historical and traditional reasons, libcurl has a built-in progress meter that can be switched on and then makes it present a progress meter in your terminal.

Switch on the progress meter by, oddly enough, setting CURLOPT_NOPROGRESS to zero. This option is set to 1 by default.

For most applications however, the built-in progress meter is useless and what instead is interesting is the ability to specify a progress callback. The function pointer you pass to libcurl will then be called on irregular intervals with information about the current transfer.

Set the progress callback by using CURLOPT_PROGRESSFUNCTION. And pass a pointer to a function that matches this prototype:

int progress_callback(void *clientp,double dltotal,double dlnow,double ultotal,double ulnow);

If any of the input arguments is unknown, a 0 will be passed. The first argument, the ‘clientp’ is the pointer you pass to libcurl with CURLOPT_PROGRESSDATA. libcurl won’t touch it.

开始:
根据上面的文档,实现我们自己的progress_func:

int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded)
{int totaldotz=40;double fractiondownloaded = NowDownloaded / TotalToDownload;int dotz = round(fractiondownloaded * totaldotz);int ii=0;printf("%3.0f%% [",fractiondownloaded*100);for ( ; ii printf("=");}for ( ; ii printf(" ");}printf("]\r");fflush(stdout);
}

同样根据文档:
setting CURLOPT_NOPROGRESS to zero
Set the progress callback by using CURLOPT_PROGRESSFUNCTION

FILE *file_param;
file_param = fopen("download_to_path", "wb");curl_easy_setopt(curl, CURLOPT_WRITEDATA, file_param); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_func)

最后看一个完整的官方例子:
https://curl.haxx.se/libcurl/c/progressfunc.html
不同的版本,不同的处理:

#include
#include #define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3struct myprogress {double lastruntime;CURL *curl;
};static int xferinfo(void *p,curl_off_t dltotal, curl_off_t dlnow,curl_off_t ultotal, curl_off_t ulnow)
{struct myprogress *myp = (struct myprogress *)p;CURL *curl = myp->curl;double curtime = 0;curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {myp->lastruntime = curtime;fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);}fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T"\r\n",ulnow, ultotal, dlnow, dltotal);if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
return 1;
return 0;
}/* for libcurl older than 7.32.0 (CURLOPT_PROGRESSFUNCTION) */
static int older_progress(void *p,double dltotal, double dlnow,double ultotal, double ulnow)
{
return xferinfo(p,(curl_off_t)dltotal,(curl_off_t)dlnow,(curl_off_t)ultotal,(curl_off_t)ulnow);
}int main(void)
{CURL *curl;CURLcode res = CURLE_OK;struct myprogress prog;curl = curl_easy_init();if(curl) {prog.lastruntime = 0;prog.curl = curl;curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, older_progress);/* pass the struct pointer into the progress function */ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);#if LIBCURL_VERSION_NUM >= 0x072000/* xferinfo was introduced in 7.32.0, no earlier libcurl versions willcompile as they won't have the symbols around.If built with a newer libcurl, but running with an older libcurl:curl_easy_setopt() will fail in run-time trying to set the newcallback, making the older callback get used.New libcurls will prefer the new callback and instead use that one evenif both callbacks are set. */ curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);/* pass the struct pointer into the xferinfo function, note that this isan alias to CURLOPT_PROGRESSDATA */ curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
#endifcurl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);res = curl_easy_perform(curl);if(res != CURLE_OK)fprintf(stderr, "%s\n", curl_easy_strerror(res));/* always cleanup */ curl_easy_cleanup(curl);}
return (int)res;
}


推荐阅读
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 由于同源策略的限制,满足同源的脚本才可以获取资源。虽然这样有助于保障网络安全,但另一方面也限制了资源的使用。那么如何实现跨域呢,以下是实现跨域的一些方法。 ... [详细]
  • Windows简单部署Exceptionless
    部署准备Elasticsearch、Exceptionless.API、Exceptionless.UI、URLRewrite、.NET运行时 1、安装ElasticSearch1 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 本文介绍了贝叶斯垃圾邮件分类的机器学习代码,代码来源于https://www.cnblogs.com/huangyc/p/10327209.html,并对代码进行了简介。朴素贝叶斯分类器训练函数包括求p(Ci)和基于词汇表的p(w|Ci)。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
author-avatar
safecaps
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有