开发需要写了一个处理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. SQL Server 2012 读写分离设置

    SQL Server 2012 读写分离设置 - AlsoIn 时间 2014-07-21 17:38:00  博客园-所有随笔区 原文  http://www.cnblogs.com/also/p/ ...

  2. if (!floor) 小明.跳楼(); 请问小明会在哪些楼层跳楼?

    博客已经迁移到www.imyzf.com,本站不再更新,请谅解! 看到标题请先思考一下这个奇葩的问题..答案在文章最后揭晓.. 会出现这个问题的起源是这样的,一个同学问我: int main() { ...

  3. nginx错误日志error_log日志级别

    error_log 级别分为 debug, info, notice, warn, error, crit  默认为crit,

  4. platform平台设备驱动简化示例代码

    driver.c: #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h& ...

  5. Codeforces Round #345 (Div. 1) A. Watchmen 模拟加点

    Watchmen 题意:有n (1 ≤ n ≤ 200 000) 个点,问有多少个点的开平方距离与横纵坐标的绝对值之差的和相等: 即 = |xi - xj| + |yi - yj|.(|xi|, |y ...

  6. 魔兽争霸Ⅲ运行时不能初始化directX的错误解决

    运行魔兽争霸3不能初始化DirectX错误这样解决: 1:在运行中输入(win+r):dxdiag,查看显示栏,确定电脑已安装好directx 8.1以上,且下面的三个加速都已开启. 2:如果没有安装 ...

  7. xcode 中添加pch文件

    xcode6以后去掉了pch文件,据说苹果是觉得把头文件加在pch中,会让编译变慢,但是作为我们程序员来说难不倒我们,所以我们手动来添加一下pch文件即可   首先创建一个工程,然后创建一个pch文件 ...

  8. Tesseract——OCR图像识别 入门篇

    Tesseract——OCR图像识别 入门篇 最近给了我一个任务,让我研究图像识别,从我们项目的screenshot中识别文字信息,so我开始了学习,与大家分享下. 我看到目前OCR技术有很多,最主要 ...

  9. [转].NET程序在windows操作系统上独立运行的技术要点

    发现一个不错的网站,转载一篇文章方便查看 转自 http://www.linuxdot.net/bbsfile-3354   ===================================== ...

  10. 看看baidu是如何AJAX跨域的[转]

    看看baidu是如何AJAX跨域的 最近做个人网站遇到AJAX跨子域名的问题. 偶尔看到baidu的通行证处理都是在二级域名passport.baidu.com中处理的, 但是baidu很多地方登录都 ...