curl 实现下载文件特定片段

来源:互联网 发布:unity3d 联网游戏视频 编辑:程序博客网 时间:2024/04/29 05:47

通过设置CURLOPT_RANGE可以下载服务器端文件的特定数据块,这样如果服务器数据很大的情况下,如果只是需其中一小块数据就可以采用这种方法

当然这个也可以用来多线程加速下载同一个文件


#include "stdafx.h"#include "curl/curl.h"#include <string>/*注意包含这个头文件后必须把share.h重命名一下,可能是stl里面也有这个头文件,比如curl_share.h,然后把包含到的地方替换一下*/#include "curl/easy.h"using namespace std;struct RecordNode{public:int idx;int data[10000];void SetData(int i){idx = i;for ( int j = 0; j < 10000; j ++ ){data[j] = i + j;}}};struct BufferNode{char ptrBuff[40004];int cur;int max;};BufferNode node;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;BufferNode* pBuf = /*&node;*/(BufferNode*)userdata;size_t cnt = size * nmemb;if ( pBuf->cur + nmemb <= pBuf->max ){memcpy(&(pBuf->ptrBuff[pBuf->cur]), ptr, cnt);pBuf->cur += cnt;}else{//printf("over flow...\n");memcpy(&(pBuf->ptrBuff[pBuf->cur]), ptr, pBuf->max - pBuf->cur);pBuf->cur += pBuf->max - pBuf->cur;}return nmemb;}int assetsManagerProgressFunc(void *ptr, double totalToDownload, double nowDownloaded, double totalToUpLoad, double nowUpLoaded){static int percent = 0;int tmp = 0;if ( totalToDownload > 0 ){tmp = (int)(nowDownloaded / totalToDownload * 100);}printf("下载进度%0d%%\r", tmp);return 0;}bool downLoad(void *_curl, std::string _packageUrl, int idx ){// Create a file to save package.//BufferNode node;node.cur = 0;node.max = sizeof(RecordNode);//node.ptrBuff = new char[node.max];char szRange[128] ={};size_t nodeSize = sizeof(RecordNode);sprintf( szRange, "%d-%d", idx * nodeSize, (idx + 1)*nodeSize );// Download pacakgeCURLcode res;curl_easy_setopt(_curl, CURLOPT_URL, _packageUrl.c_str());curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, downLoadPackage);curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &node);curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, false);curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, assetsManagerProgressFunc);//curl_easy_setopt(_curl, CURLOPT_PROGRESSDATA, this);curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1L);curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_LIMIT, 1L);curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_TIME, 5L);curl_easy_setopt(_curl, CURLOPT_TIMEOUT, 20);        //设置超时 curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1);        //屏蔽其它信号 curl_easy_setopt(_curl, CURLOPT_HEADER, 0);          //下载数据包括HTTP头部 curl_easy_setopt(_curl, CURLOPT_RANGE, /*"0-500"*/szRange);     //用于断点续传, 设置下载的分片 res = curl_easy_perform(_curl);curl_easy_cleanup(_curl);if (res != 0){printf("error: failed to download data\n");return false;}if(node.cur == node.max){RecordNode record;memcpy(&record, node.ptrBuff, sizeof(RecordNode));printf(".....idx:%d,data3:%d.......\n", record.idx, record.data[2]);}else{printf("error: data not correct\n");}//delete[] node.ptrBuff;return true;}void GenerateData(){FILE *fp = fopen("records.dat", "wb");if (!fp){return;}for ( int i = 0; i < 10000; i ++ ){RecordNode node;node.SetData(i);size_t written = fwrite(&node, sizeof(RecordNode), 1, fp);}fclose(fp);fp = fopen("records.dat", "rb");if (!fp){return;}RecordNode nodeBuf;fread(&nodeBuf, sizeof(RecordNode), 1, fp);printf("idx:%d,data3:%d\n", nodeBuf.idx, nodeBuf.data[2]);fseek(fp,-1 * int(sizeof(RecordNode)), SEEK_END);fread(&nodeBuf,sizeof(RecordNode), 1, fp);printf("idx:%d,data3:%d\n", nodeBuf.idx, nodeBuf.data[2]);fclose(fp);}int _tmain(int argc, _TCHAR* argv[]){//GenerateData();CURL* _curl = curl_easy_init();if (! _curl){return 0;}//downLoad(_curl, "http://ardownload.adobe.com/pub/adobe/reader/win/11.x/11.0.01/en_US/AdbeRdr11001_en_US.exe", "./", "AdbeRdr11001_en_US.exe");downLoad(_curl, "http://localhost/records.dat", 1);_curl = curl_easy_init();downLoad(_curl, "http://localhost/records.dat", 10);_curl = curl_easy_init();downLoad(_curl, "http://localhost/records.dat", 28);getchar();return 0;}

0 0
原创粉丝点击