热门标签 | 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;
}


推荐阅读
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • Linux CentOS 7 安装PostgreSQL 9.5.17 (源码编译)
    近日需要将PostgreSQL数据库从Windows中迁移到Linux中,LinuxCentOS7安装PostgreSQL9.5.17安装过程特此记录。安装环境&#x ... [详细]
  • SvpplyTable: 实现可扩展和可折叠的菜单动画
    SvpplyTable 是一个示例项目,旨在实现类似 Svpply 应用程序中的可扩展和可折叠的菜单动画效果。该项目托管在 GitHub 上,地址为 https://github.com/liuminqian/SvpplyTable。 ... [详细]
  • 本文详细介绍如何在忘记MySQL服务器密码的情况下进行密码重置,包括具体的步骤和注意事项。 ... [详细]
  • 如何配置VisualSVN以确保提交时必须填写日志信息
    在软件开发团队中,成员们有时会忘记在提交代码时添加必要的备注信息。为了规范这一流程,可以通过配置VisualSVN来强制要求团队成员在提交文件时填写日志信息。本文将详细介绍如何设置这一功能。 ... [详细]
  • 小程序的授权和登陆
    小程序的授权和登陆 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 本文介绍了如何利用HTTP隧道技术在受限网络环境中绕过IDS和防火墙等安全设备,实现RDP端口的暴力破解攻击。文章详细描述了部署过程、攻击实施及流量分析,旨在提升网络安全意识。 ... [详细]
  • 体积小巧的vsftpd与pureftpd Docker镜像在Unraid系统中的详细配置指南:支持TLS加密及IPv6协议
    本文详细介绍了如何在Unraid系统中配置体积小巧的vsftpd和Pure-FTPd Docker镜像,以支持TLS加密和IPv6协议。通过这些配置,用户可以实现安全、高效的文件传输服务,适用于各种网络环境。配置过程包括镜像的选择、环境变量的设置以及必要的安全措施,确保了系统的稳定性和数据的安全性。 ... [详细]
  • 【Linux】CentOS 7 远程连接指南:高效安全的远程管理方法
    在 CentOS 7 中实现高效且安全的远程管理,本文详细介绍了如何检查和安装配置 OpenSSH。首先,通过 `yum list installed` 命令检查系统是否已安装 OpenSSH,若未安装,则使用 `yum install openssh-server` 进行安装。随后,配置 SSH 服务以确保其安全性和稳定性,包括修改默认端口、禁用 root 登录等关键步骤。此外,还提供了常见问题的解决方案,帮助用户顺利进行远程连接。 ... [详细]
  • 介绍如何使用 `document.createElementNS` 方法创建带有特定命名空间 URI 和限定名称的元素。 ... [详细]
  • 2018年在北航听陈博士讲解时,对重入漏洞有了初步了解。最近重温了慢雾科技的相关文章,发现他们对重入漏洞的解释非常清晰明了。 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 深入解析OSI七层架构与TCP/IP协议体系
    本文详细探讨了OSI七层模型(Open System Interconnection,开放系统互连)及其与TCP/IP协议体系的关系。OSI模型将网络通信过程划分为七个层次,每个层次负责不同的功能,从物理层到应用层逐步实现数据传输和处理。通过对比分析,本文揭示了OSI模型与TCP/IP协议在结构和功能上的异同,为理解现代网络通信提供了全面的视角。 ... [详细]
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社区 版权所有