.h文件:
#pragma once
#include "cocos2d.h"
class downloadPhoto : public cocos2d::CCObject
{
public:
static downloadPhoto *m_inst;
static downloadPhoto *GetInst();
bool DownLoadFile(std::string filename, std::string foldername);
long getLocalFileLenth(const char* filename);
static int progressFunc(void *ptr, double totalToDownload, double nowDownloaded, double totalToUpLoad, double nowUpLoaded);
static size_t downLoadPackage(void *ptr, size_t size, size_t nmemb, void *userdata);
double getDownloadFileLenth(const char *url);
static size_t save_header(void *ptr, size_t size, size_t nmemb, void *data);
static size_t writefunc(void *ptr, size_t size, size_t nmemb, void *userdata);
FILE* createFile(const char *file);
};
.cpp文件:
#include "downloadPhoto.h"
#include "curl.h"
#include "deprecated\CCDeprecated.h"
#include <string>
#ifdef WIN32
#include <direct.h>
#else
#include <sys/stat.h>
#include <unistd.h>
#endif
using namespace cocos2d;
downloadPhoto* downloadPhoto::m_inst = NULL;
downloadPhoto* downloadPhoto::GetInst()
{
if (!m_inst)
{
m_inst = new downloadPhoto();
return m_inst;
}
return NULL;
}
bool downloadPhoto::DownLoadFile(std::string filename, std::string foldername)
{
std::string fullpath = CCFileUtils::sharedFileUtils()->getWritablePath() + filename;
FILE *fp = NULL;
fp = createFile(fullpath.c_str());
//if (access(fullpath.c_str(), 0) == 0)
//{
// fp = fopen(fullpath.c_str(), "ab+"); //追加方式打开
//}
//else
//{
// fp = fopen(fullpath.c_str(), "wb"); //创建方式打开
//}
if (fp == NULL)
{
return false;
}
long localFileLenth = getLocalFileLenth(filename.c_str()); //已经下载的大小
long timeout = 10;
std::string downloadUrl = "http://123.456.789/folder/";
CURLcode res;
std::string packageUrl = downloadUrl + foldername + "/" + filename; //下载地址+下载文件名
double filesize = getDownloadFileLenth(packageUrl.c_str());
if (filesize == -1 || filesize == 0)
{
return false;
}
CURL *_curl;
_curl = curl_easy_init();
if (!_curl)
{
curl_easy_cleanup(_curl);
curl_global_cleanup();
return false;
}
curl_easy_setopt(_curl, CURLOPT_URL, packageUrl.c_str());
curl_easy_setopt(_curl, CURLOPT_TIMEOUT, timeout); //timeout秒下载时间
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, downLoadPackage); //写文件回调方法
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(_curl, CURLOPT_RESUME_FROM, localFileLenth); //断点续传位置
curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, 0);
curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, progressFunc); //下载进度回调方法
res = curl_easy_perform(_curl);
curl_easy_cleanup(_curl);
curl_global_cleanup();
fclose(fp);
if (res != 0) {
return false;
}
else {
return true;
}
}
FILE* downloadPhoto::createFile(const char *file)
{
if (!file)
return NULL;
char buf[260];
const char *pStart = file + 1;
const char *pEnd = NULL;
do
{
pEnd = strchr(pStart, '/');
if (pEnd)
{
memcpy(buf, file, pEnd - file);
buf[pEnd - file] = 0;
pStart = ++pEnd;
if (chdir(buf) == -1)
#ifdef WIN32
if (mkdir(buf))
#else
if (mkdir(buf, S_IRWXU))
#endif
{
//cocos2d::CCLog("failed to mkdir: %d", errno);
return NULL;
}
}
else
{
FILE *fp;
if ((fp = fopen(file, "ab+")) == 0)
return NULL;
return fp;
}
} while (1);
return NULL;
}
long downloadPhoto::getLocalFileLenth(const char* filename)
{
std::string fullPath = CCFileUtils::sharedFileUtils()->getWritablePath() + filename;
FILE *fp = fopen(fullPath.c_str(), "r");
fseek(fp, 0, SEEK_END);
long length = ftell(fp);
fclose(fp);
return length;
}
int downloadPhoto::progressFunc(void *ptr, double totalToDownload, double nowDownloaded, double totalToUpLoad, double nowUpLoaded)
{
//当前下载文件的总体大小totalToDownload
//当前下载的大小nowDownloaded
//当前下载的文件进度
float curpercent = nowDownloaded / totalToDownload * 100;
return 0;
}
size_t downloadPhoto::downLoadPackage(void *ptr, size_t size, size_t nmemb, void *userdata)
{
FILE *fp = (FILE*)userdata;
size_t written = fwrite(ptr, size, nmemb, fp);
return written;
}
double downloadPhoto::getDownloadFileLenth(const char *url){
double len = 0.0;
CURL *handle = curl_easy_init();
if (!handle)
{
curl_easy_cleanup(handle);
curl_global_cleanup();
return 0;
}
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_setopt(handle, CURLOPT_HEADER, 1); //只要求header头
curl_easy_setopt(handle, CURLOPT_NOBODY, 1); //不需求body
curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, save_header);
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writefunc);
if (curl_easy_perform(handle) == CURLE_OK) {
if (CURLE_OK == curl_easy_getinfo(handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &len)){
}
else {
//curl_easy_getinfo failed!
len = -1;
}
}
else {
len = -1;
}
curl_easy_cleanup(handle);
curl_global_cleanup();
return len;
}
size_t downloadPhoto::save_header(void *ptr, size_t size, size_t nmemb, void *data)
{
return (size_t)(size * nmemb);
}
size_t downloadPhoto::writefunc(void *ptr, size_t size, size_t nmemb, void *userdata)
{
return (size_t)(size * nmemb);
}