libcurl是一个很强大的开源网络处理库,支持包括HTTP、HTTPS、FTP……一系列网络协议。用它来进行HTTP的get\post 或者下载文件更是小菜一碟,chrome内核都用到了它,本文主要讲解一个使用curl下载文件的小例。

首先是去下载curl的最新源代码,然后编译成动态库或者静态库;然后把头文件和库文件拿出来加入到我们自己的工程中,引用声明:

#include "curl.h"
#ifdef _DEBUG
#pragma comment(lib, "../Debug/libcurld")
#else
#pragma comment(lib, "../Release/libcurl")
#endif

特意在原有代码上加了一些注释,希望可以更好理解,上代码:

<pre name="code" class="cpp">// UseLibCurl.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <Windows.h>
#include <CommCtrl.h>
#include "resource.h"
#include "curl.h"
#ifdef _DEBUG
#pragma comment(lib, "../Debug/libcurld")
#else
#pragma comment(lib, "../Release/libcurl")
#endif //这个用来保存对话框的窗口句柄,因为后面要向这个窗口发消息,必须知道其窗口句柄
HWND g_hDlgWnd = NULL;
//提供给CURL下载进度回调的函数,用于保存下载的数据到文件
static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam);
//提供给CURL下载进度回调的函数,用于计算下载进度通知界面
static int ProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
//这是对话框的消息循环,在控制台程序里面创建GUI,仅仅是为了更好地展现下载回调这个功能
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//这个是下载的线程函数,为了不把对话框主界面卡死,肯定是要自己开线程来下载的了
DWORD WINAPI DownloadThread(LPVOID lpParam); int _tmain(int argc, _TCHAR* argv[])
{
//弹出对话框,知道对话框关闭才会执行退出
DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc );
return ;
} static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam)
{
//把下载到的数据以追加的方式写入文件(一定要有a,否则前面写入的内容就会被覆盖了)
FILE* fp = NULL;
fopen_s(&fp, "c:\\test.apk", "ab+");
size_t nWrite = fwrite(pBuffer, nSize, nMemByte, fp);
fclose(fp);
return nWrite;
} static int ProgressCallback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
if ( dltotal > -0.1 && dltotal < 0.1 )
return ;
int nPos = (int) ( (dlnow/dltotal)* );
//通知进度条更新下载进度
::PostMessage(g_hDlgWnd, WM_USER + , nPos, );
//::Sleep(10);
return ;
} INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch( uMsg )
{
case WM_INITDIALOG:
{
g_hDlgWnd = hWnd;
HWND hProgress = GetDlgItem(hWnd, IDC_PROGRESS1);
SendMessage(hProgress, PBM_SETRANGE32, (WPARAM) , (LPARAM) );
//对话框初始化时创建下载线程
HANDLE hThread = CreateThread(NULL, , DownloadThread, , , NULL);
CloseHandle(hThread);
::SetWindowText(hWnd, L"使用CURL下载文件示例:");
return TRUE;
}
case WM_COMMAND:
{
WORD msg = HIWORD(wParam);
WORD id = LOWORD(wParam);
if ( id == IDOK || id == IDCANCEL )
EndDialog(hWnd, id);
break;
}
case WM_ERASEBKGND:
return TRUE;
case WM_CTLCOLORSTATIC:
return (INT_PTR)(HBRUSH)::GetStockObject(WHITE_BRUSH);
case WM_USER + :
{//接收到设置进度的消息
HWND hProgress = GetDlgItem(hWnd, IDC_PROGRESS1);
HWND hStatus = GetDlgItem(hWnd, IDC_STATUS);
if ( hProgress )
SendMessage(hProgress, PBM_SETPOS, wParam, 0L);
if ( hStatus )
{
WCHAR szBuffer[] = {};
if ( wParam< )
swprintf(szBuffer, L"正在下载文件,进度:%d%%", wParam);
else
swprintf(szBuffer, L"文件下载完毕!");
::SetWindowText(hStatus, szBuffer);
}
return ;
}
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
} DWORD WINAPI DownloadThread(LPVOID lpParam)
{
//初始化curl,这个是必须的
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://android.shoujids.com/software/download?id=154103");
//设置接收数据的回调
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DownloadCallback);
//curl_easy_setopt(curl, CURLOPT_INFILESIZE, lFileSize);
//curl_easy_setopt(curl, CURLOPT_HEADER, 1);
//curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
//curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
// 设置重定向的最大次数
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, );
// 设置301、302跳转跟随location
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, );
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, );
//设置进度回调函数
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, ProgressCallback);
//curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &lFileSize);
//curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, g_hDlgWnd);
//开始执行请求
CURLcode retcCode = curl_easy_perform(curl);
//查看是否有出错信息
const char* pError = curl_easy_strerror(retcCode);
//清理curl,和前面的初始化匹配
curl_easy_cleanup(curl);
return ;
}

原文链接:使用libcurl下载文件小例

使用libcurl下载文件小例的更多相关文章

  1. libcurl下载文件

    一.初始化 CURL *pHandler = curl_easy_init();   二.设置请求参数: 调用curl_easy_setopt方法,设置选项 curl_easy_setopt(pHan ...

  2. asm下重定向数据文件小例(使用toad工具)

    原创作品,出自 "深蓝的blog" 博客,深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/46863991 场景 ...

  3. 【windows核心编程】IO完成端口(IOCP)复制文件小例

    1.演示内容 文件复制 2.提要 复制大文件时,使用FILE_FLAG_NO_BUFFERING标志 同时需要注意: 读写文件的偏移地址为 磁盘扇区 的整数倍 读写文件的字节数为 磁盘扇区 的整数倍 ...

  4. 【windows核心编程】IO完成端口(IOCP)复制文件小例前简单说明

    1.关于IOCP IOCP即IO完成端口,是一种高伸缩高效率的异步IO方式,一个设备或文件与一个IO完成端口相关联,当文件或设备的异步IO操作完成的时候,去IO完成端口的[完成队列]取一项,根据完成键 ...

  5. c/c++常用代码--使用libcurl下载文件

    #pragma once #include <stdio.h>#include <stdlib.h> #include <curl/curl.h> #ifdef   ...

  6. libcurl下载文件简易demo

    size_t test_save(void *ptr, size_t size, size_t nmemb, void *stream) { size_t sizes = size * nmemb; ...

  7. 如何用ajax下载文件

    引子 在HTML5没来之前,浏览器想要下载文件,可能有这么几种方式: 借助a标签,<a href="学习资料.xlsx"></a> window.locat ...

  8. 【转】【Python】python使用urlopen/urlretrieve下载文件时出现403 forbidden的解决方法

    第一:urlopen出现403 #!/usr/bin/env python # -*- coding: utf- -*- import urllib url = "http://www.go ...

  9. java实现FTP下载文件

    ftp上传下载文件,是遵照ftp协议上传下载文件的,本例仅以下载文件为例. 重要的方法解释: 1.FTP功能相关依赖路径:org.apache.commons.net.ftp.*: 2.ftp默认端口 ...

随机推荐

  1. Winform DataGridView列的单元格中动态添加图片和文字

    先上图在说,第二列中图片和文字的样式 1.需要重写DataGridViewTextBoxColumn,新建类TextAndImageColumn.cs using System; using Syst ...

  2. JAVA_SE_Day02 String 的正则表达式

    字符串支持正则表达式的方法一: boolean matches(String regex) 注意: 给定的正则表达式就算不指定边界符(^,$),也会全匹配验证 空字符串和null 空字符串是看不见,而 ...

  3. Nginx 504错误总结

    Nginx 504错误(Gateway time-out  网关超时)的含义是所请求的网关没有请求到,简单来说就是没有请求到可以执行的PHP-CGI. 一般看来, 这种情况可能是由于nginx默认的f ...

  4. JBPM学习第1篇:入门与安装

    1.相关关键词 BPM:全称Business Process Management,即业务流程管理 BPEL:全称为Business Process Execution Language,即业务流程执 ...

  5. Mybatis执行sql(insert、update、delete)返回值问题

    数据库:Mysql 在使用mybatis的过程中对执行sql的返回值产生疑问,顺手记录一下. 结论: insert:   插入n条记录,返回影响行数n.(n>=1,n为0时实际为插入失败) up ...

  6. 关于Sychronized和volatile自己总结的一点点理解(草稿)

    问答形式列举: 1. 为什么说sychronized能保证可见性 synchronized和Lock能保证同一时刻只有一个线程获取锁然后执行同步代码,并且在释放锁之前会将对变量的修改刷新到主存当中.因 ...

  7. java中如何使用BigDecimal使得Double类型保留两位有效数字

    一.场景:从数据表中读出Decimal类型的数据直接塞给Double类型的对象时,并不会有什么异常. 如果要再此基础上计算,就会发生异常. 比如:读出数据为0.0092,将其乘以100,则变成了0.9 ...

  8. Git Bash Here常用命令以及使用步骤

    1.首先,要clone项目代码: git clone 链接地址 2.更新代码: git pull 3.添加修改过的文件.文件夹: git add 修改过的文件,文件夹 4.提交并注释: git com ...

  9. QQ 聊天机器人小薇发布!

    简介 XiaoV(小薇)是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动: 监听多个 QQ 群消息,发现有"感兴趣"的内容时通过图灵机器人进行智能回复 监 ...

  10. Linux符设备驱动编程

    加入内核源码树外 ① 建立两个文件scull.c,scull.h,以及Makefile文件 Makefile文件 ② 用make进行编译,生成scull.ko驱动程序模块 ③ 把scull.ko模块加 ...