开发需要写了一个处理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. VS2013中Django流水账笔记--配置环境

    一.开发环境 Win7 64位搭建开发环境.需要准备VS2013.Python34.PTVS2013. 1.http://pytools.codeplex.com/ 下载工具,下载之后进行安装即可,我 ...

  2. (转)HTTP协议(2)

    转自:http://kb.cnblogs.com/page/130970/  作者 :小坦克 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无 ...

  3. jquery 循环显示div的示例代码

    我们用一个语句就让下面五个div显示成功,具体实现如下,感兴趣的朋友可以参考下 直接看例子 复制代码代码如下: for(var p=1; p<=5; p++){  $("#proper ...

  4. javascript操作html元素CSS属性

    下面先记录一下JS控制CSS所使用的方法. 1.使用javascript更改某个css class的属性... <style type="text/css"> .ori ...

  5. pymssql 安装测试

    平台 : windows 7 32位 数据库 : SQLSERVER 2008 python 2.7  & pymssql模块 数据库和python 等模块安装说明省略 以下贴出测试代码: 单 ...

  6. uCGUI窗口初始化过程

    一.相关结构体和变量 重要的uCGUI系统全局变量 NextDrawWin                      下一个需要重绘的窗口句柄 WM__NumWindows       系统当前的总共 ...

  7. 【Git 】$ ./gradlew idea 构建一个idea的项目

    Welcome to Git (version 1.9.5-preview20150319) Run 'git help git' to display the help index.Run 'git ...

  8. js: get event handler bound to the element

    jQuery._data(jQuery(this)[0], "events" ).click[0].handler $._data( $("#myabc")[0 ...

  9. cocos2dx android平台事件系统解析

    对于cocos2dx在android平台事件的响应过程很模糊,于是分析了下源码,cocos2dx 版本3.4,先导入一个android工程,然后看下AndroidManifest.xml <ap ...

  10. Pair Project: Elevator Scheduler [电梯调度算法的实现和测试][关于电梯调度算法的附加思考]:刘耀先-11061183,罗凡-11061174

    本文为对于电梯调度算法的三个附加题思考 1.改进电梯调度的interface 设计, 让它更好地反映现实, 更能让学生练习算法, 更好地实现信息隐藏和信息共享. <1>进一步提高API定义 ...