开发需要写了一个处理curl 下载的c++类,内含有多个静态方法和实例方法,写在这里留给有需求的同学

头文件

CURLHelper.h

enum CURLHelperStateType
{
CURLHelper_START = ,
CURLHelper_PROGRESS = ,
CURLHelper_COMPLETE = ,
CURLHelper_UNKNOW =
}; class CURLHelper
{
public:
static std::string getHttpString(const char * url); static long getDownloadFileSize(const char *url); static long getLocalFileSize(const char *localpath); CURLHelper();
~CURLHelper(); void downloadFile(const char *url,const char *localpath); void downloadProgressCallback(double percent); long getTotalFileSize(); CURLHelperStateType getState(); double getPercent(); void doDownload();
private:
string m_url;
string m_local_path; double m_fileTotalSize;
// double m_currentFileSize; double m_percent; pthread_t *pDownloadThread; int reDownloadCount;
CURLHelperStateType m_currentState;
};
/**
* 获取服务器文件的字符 ,阻塞式
* @param url
* @return
*/
string CURLHelper::getHttpString(const char *url)
{
std::string str = "";
CURL *_curl = curl_easy_init();
if (! _curl)
{
CCLOG("can not init curl");
return str;
}
curl_easy_setopt(_curl, CURLOPT_URL, url);
curl_easy_setopt(_curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, getCharCode);
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &str); CURLcode res = curl_easy_perform(_curl);
if (res != CURLE_OK)
{
CCLOG("can not get version file content, error code is %d", res);
curl_easy_cleanup(_curl);
return str;
}
curl_easy_cleanup(_curl);
return str;
}
/**
* 获取服务器上的文件物理大小
* @param url
* @return
*/
long CURLHelper::getDownloadFileSize(const char *url)
{
double downloadFileLenth = ;
CURL *handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_setopt(handle, CURLOPT_HEADER, ); //只需要header头
curl_easy_setopt(handle, CURLOPT_NOBODY, ); //不需要body
if (curl_easy_perform(handle) == CURLE_OK)
{
curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &downloadFileLenth);
}
else
{
downloadFileLenth = -;
}
return downloadFileLenth;
}
/**
* 获取本地文件大小
* @param localpath
* @return
*/
long CURLHelper::getLocalFileSize(const char *localpath)
{
curl_off_t local_file_len = ;
struct stat file_info;
if(stat(localpath, &file_info) == )
{
local_file_len = file_info.st_size;
}
return local_file_len;
} /* 保存下载文件 */ size_t wirtefunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
FILE *fp = (FILE*)stream;
size_t written = fwrite(ptr, size, nmemb, fp);
return written;
}
/* 下载回调的计算进度条的函数 */
static int progress_func(void *ptr, double totalToDownload, double nowDownloaded, double totalToUpLoad, double nowUpLoaded)
{
CURLHelper *helper = (CURLHelper*)ptr;
double curpercent = * nowDownloaded / totalToDownload; helper->downloadProgressCallback(curpercent);
return ;
} void CURLHelper::doDownload()
{
do
{
string tmpPath = m_local_path + ".tmp";
FILE *localFile = NULL; double m_currentTmpSize = CURLHelper::getLocalFileSize(tmpPath.c_str()); if (m_currentTmpSize > )
{
localFile = fopen(tmpPath.c_str(), "ab+");
CCLOG("断点下载模式");
}
else
{
localFile = fopen(tmpPath.c_str(), "wb+");
}
int cc = error_no();
if (!localFile)
{
break;
}
m_currentState = CURLHelper_PROGRESS;
CURL *curlhandle = curl_easy_init();
curl_easy_setopt(curlhandle, CURLOPT_URL, m_url.c_str()); //写函数回调
curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, localFile);
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, wirtefunc);
//断点下载
curl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM_LARGE, m_currentTmpSize);
//下载进度回调
curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curlhandle, CURLOPT_PROGRESSFUNCTION, progress_func);
curl_easy_setopt(curlhandle, CURLOPT_PROGRESSDATA, this); CURLcode res = curl_easy_perform(curlhandle);
fclose(localFile);
curl_easy_cleanup(curlhandle); if (res == CURLE_OK)
{
//文件改名
int result = rename(tmpPath.c_str(), m_local_path.c_str());
int e = error_no();
if (result == )
{
CCLOG("改名成功");
}
else
{
CCLOG("rename failed %d",e);
}
}
else
{
CCLOG("下载失败,CURLcode %d",res);
if (reDownloadCount < )
{
//直接删除缓存文件
int removeCode = remove(tmpPath.c_str());
CCLOG("下载失败,删除tmp文件,并重新下载 %d",removeCode);
reDownloadCount++;
m_currentState = CURLHelper_START;
doDownload();
return;
}
} }
while ();
m_currentState = CURLHelper_COMPLETE;
} CURLHelper::CURLHelper()
{
m_currentState = CURLHelper_UNKNOW;
pDownloadThread = NULL;
m_percent = ;
reDownloadCount = ;
} CURLHelper::~CURLHelper()
{
CCLOG("~CURLHelper");
if (pDownloadThread)
{
delete pDownloadThread;
}
}
long CURLHelper::getTotalFileSize()
{
return m_fileTotalSize;
}
CURLHelperStateType CURLHelper::getState()
{
return m_currentState;
} static void *thread_downloadFiles(void* data)
{
CURLHelper *helper = (CURLHelper*)data;
helper->doDownload();
return NULL;
} void CURLHelper::downloadFile(const char *url, const char *localpath)
{
m_url = url;
m_local_path = localpath;
m_fileTotalSize = CURLHelper::getDownloadFileSize(url);
m_percent = ;
//记录当前状态
m_currentState = CURLHelper_START;
//开启线程下载
pDownloadThread = new pthread_t();
pthread_create(&(*pDownloadThread), NULL, thread_downloadFiles, (void*)this);
}
void CURLHelper::downloadProgressCallback(double percent)
{
m_percent = percent;
}
double CURLHelper::getPercent()
{
return m_percent;
}

libcurl断点下载的更多相关文章

  1. libcurl断点下载遇到的问题

    最近游戏把资源(图片.配置.lua)的加载.更新全部改了 ,加载其实还好,就是不走之前的zip解压方式.   以前的大体流程: 下载 –> 启动 –> 解压 –> 更新 –> ...

  2. 使用libCurl实现断点下载

    关键部分代码如下: #include "curl.h" #pragma comment(lib, "libcurl.lib") size_t CROS_Down ...

  3. Java实现多线程断点下载(下载过程中可以暂停)

    线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...

  4. 安卓(android)之实现断点下载功能

    一.建立实体类 1.文件实体类 package com.example.zjw.myapplication.dao; import java.io.Serializable; /** * 预下载文件实 ...

  5. iOS 大文件断点下载

    iOS 在下载大文件的时候,可能会因为网络或者人为等原因,使得下载中断,那么如何能够进行断点下载呢? // resumeData的文件路径 #define XMGResumeDataFile [[NS ...

  6. 【Java EE 学习 22 下】【单线程下载】【单线程断点下载】【多线程下载】

    一.文件下载简述 1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息 (1)response.setContentType("application/force-downl ...

  7. IOS 断点下载

    // // ViewController.m // UI4_断点下载 // // Created by qianfeng on 15/8/19. // Copyright (c) 2015年 ZBC. ...

  8. .net网站的文件上传读取进度条和断点下载

    文件上传到服务器时的进度读取 //调整上传配置 AdapterInfo(info); UpfileResult result = new UpfileResult(); try { //直接使用req ...

  9. iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充

    一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...

随机推荐

  1. [C#]判断字符串中是否包含中文

    关键代码: /// <summary> /// 判断字符串中是否包含中文 /// </summary> /// <param name="str"&g ...

  2. php 时间函数参考

    time()在PHP中是得到一个数字,这个数字表示从1970-01-01到现在共走了多少秒,很奇怪吧 不过这样方便计算, 要找出前一天的时间就是 time()-60*60*24; 要找出前一年的时间就 ...

  3. java JDBC操作MySQL数据库

    一,首先在MYSQL建立一个数据库,例如Geek99DB: create database Geek99DB; use Geek99DB; 然后建立一个表CustomerTab: create tab ...

  4. MVC-内容详情页显示内容

    @model InfoDataProvider.DataModel.FAQ_ContentUser 内容Content字段:如果里面有html标签. @Html.DisplayFor(p => ...

  5. online web design tool

    https://webflow.com/ http://css-tricks.com/snippets/ https://www.fluidui.com/demos

  6. java单例模式使用及注意事项

    1. 说明 1)单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例 2)单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstan ...

  7. js数值计算

    js在小数数值计算时会出现误差,比如0.19+15.02=15.20999999999999,出现此问题的原因,百度上有,为了避免误差产生可以这样做:(0.19*100+15.02*100)/100.

  8. C语言杂记

    strcmp函数是可以和int数字进行比较的 , , , }; puts(ch); if (strcmp("AAA", ch)) { printf("real?true! ...

  9. PHP之序列化与反序列化讲解

    serialize() 把变量和它们的值编码成文本形式 unserialize() 恢复原先变量 eg: $stooges = array('Moe','Larry','Curly');$new = ...

  10. PIL(Python Image Library)生成验证码

    # -*- coding: utf-8 -*-#导入三个模块import Image,ImageDraw,ImageFontimport randomimport math'''基本功能'''#图片宽 ...