您的位置:首页 > 移动开发 > Cocos引擎

cocos2d-x 脚本动态更新,curl断点续传

2014-01-03 15:41 274 查看
这里直接修改cocos2d-x-2.2.1的例子,请看CurlTest

打开头文件CurlTest.h,首先添加引用

//合并文件用
#include <io.h>
#include <memory.h>


定义用到的变量

static char *prefix = "temp";
static char *postfix = ".zip";
static long totalByte = 1869286;//需要下载的总字节数
static int tempFileNum = 0;//临时文件数量


打开CurlTest.cpp修改void CurlTest::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)

void CurlTest::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
string rootPath = CCFileUtils::sharedFileUtils()->getWritablePath();

//获得上次下载到哪里了,生成range
long fromIndex = getLastDownloadIndex(rootPath);
char rangeInfo[50];
sprintf(rangeInfo, "%d-%d", fromIndex, totalByte);
CURL *curl;
CURLcode res;
char buffer[10];
char fileName[255] = {0};
sprintf(fileName, "%s%s%d%s", rootPath.c_str(), prefix, tempFileNum, postfix);

FILE *fp = fopen(fileName, "wb");
if (! fp)
{
CCLOG("can not create file");
return ;
}
curl = curl_easy_init();
if (curl)
{

curl_easy_setopt(curl, CURLOPT_URL, "fileUrlYouWantToDownload.zip");
curl_easy_setopt(curl, CURLOPT_RANGE, rangeInfo);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, downLoadPackage);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, assetsManagerProgressFunc);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this);
curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD, downloadSpeed);
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, totalSize);

res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
if (res == 0)
{
m_pLabel->setString("0 response");
}
else
{
sprintf(buffer,"code: %i",res);
m_pLabel->setString(buffer);
}
fclose(fp);
//有多个文件,要合并
if(tempFileNum > 0 )
mergeFile(rootPath);
CCLOG("all ok!");
}
else
{
m_pLabel->setString("no curl");
}
}


这个函数通过扫描目录下的文件,计算总大小,得出上次下载了多少字节

static long getLastDownloadIndex(string rootPath)
{
FILE *file = NULL;
int index = 0;
int fileNo;
long fsize = 0;
long totalSize = 0;
tempFileNum = 0;

char fileName[255] = {0};
sprintf(fileName, "%s%s%d%s", rootPath.c_str(), prefix, index, postfix);

while(file = fopen(fileName, "rb"))
{
tempFileNum++;
fileNo = fileno(file);
totalSize += filelength(fileNo);
sprintf(fileName, "%s%s%d%s", rootPath.c_str(), prefix, ++index, postfix);

}
return totalSize;
}


写入文件的方法

static size_t 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;
}


进度处理方法

int assetsManagerProgressFunc(void *ptr, double totalToDownload, double nowDownloaded, double totalToUpLoad, double nowUpLoaded)
{
CCLOG("downloading... %d%%", (int)(nowDownloaded/totalToDownload*100));
return 0;
}


这个是为了分片下载,”0-100“表示下载0到100的字节,

curl_easy_setopt(curl, CURLOPT_RANGE, "0-100");


断点续传,必然会有分割开的文件,所以这里加个合并文件的方法
static void mergeFile(string rootPath)
{
FILE *file = NULL;
FILE *wtFile = fopen((rootPath + "saveFile.zip").c_str(), "wb");
if(!wtFile)
{
CCLOG("can't create file!");
return;
}
int index = 0;
int fileNo;
char fileName[255] = {0};
long currentFileSize = 0;
sprintf(fileName, "%s%s%d%s", rootPath.c_str(), prefix, index, postfix);
while(file = fopen(fileName, "rb"))
{
//获得文件大小
fileNo = fileno(file);
currentFileSize = filelength(fileNo);
//缓存到内存中
char *buf = new char[currentFileSize];
memset(buf, 0x0, currentFileSize);
fread(buf, currentFileSize, 1, file);
fclose(file);
fwrite(buf, currentFileSize, 1, wtFile);
delete[] buf;

sprintf(fileName, "%s%s%d%s", rootPath.c_str(), prefix, ++index, postfix);
}

fclose(wtFile);
}


文件的大小可以通过curl_easy_setopt(_curl, CURLOPT_NOBODY, 1);来只获得文件的头部,然后curl_easy_getinfo(_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &totalByte);来获得文件大小。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: