libcurl中的进度显示类似于读取数据,需要设置回调函数和回调存储数据的指针到url中,CURLOPT_PROGRESSFUNCTION传入回调函数,CURLOPT_PROGRESSDATA传入存储数据的指针。
具体实例如下:
#include <stdio.h>
#include <curl/curl.h>
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3
struct myprogress {
double lastruntime;
CURL *curl;
};
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
static int xferinfo(void *p,curl_off_t dltotal,curl_off_t dlNow,curl_off_t ultotal,curl_off_t ulNow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
double curtime = 0;
curl_easy_getinfo(curl,CURLINFO_TOTAL_TIME,&curtime);
/* under certain circumstances it may be desirable for certain functionality
to only run every N seconds,in order to do this the transaction time can
be used */
if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
myp->lastruntime = curtime;
fprintf(stderr,"TOTAL TIME: %f \r\n",curtime);
}
fprintf(stderr,"UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n",ulNow,ultotal,dlNow,dltotal);
if(dlNow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
return 1;
return 0;
}
//旧版本是参数类型double,新版本换成了curl_off_t
/* for libcurl older than 7.32.0 (CURLOPT_PROGRESSFUNCTION) */
static int older_progress(void *p,double dltotal,double dlNow,double ultotal,double ulNow)
{
return xferinfo(p,(curl_off_t)dltotal,(curl_off_t)dlNow,(curl_off_t)ultotal,(curl_off_t)ulNow);
}
int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct myprogress prog;
curl = curl_easy_init();
if(curl) {
prog.lastruntime = 0;
prog.curl = curl;
curl_easy_setopt(curl,CURLOPT_URL,"http://example.com/");
curl_easy_setopt(curl,CURLOPT_PROGRESSFUNCTION,older_progress);//回调函数
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl,CURLOPT_PROGRESSDATA,&prog);//存储数据结构体指针
#if LIBCURL_VERSION_NUM >= 0x072000
/* xferinfo was introduced in 7.32.0,no earlier libcurl versions will
compile as they won't have the symbols around.
If built with a newer libcurl,but running with an older libcurl:
curl_easy_setopt() will fail in run-time trying to set the new
callback,making the older callback get used.
New libcurls will prefer the new callback and instead use that one even
if both callbacks are set. */
curl_easy_setopt(curl,CURLOPT_XFERINFOFUNCTION,xferinfo);
/* pass the struct pointer into the xferinfo function,note that this is
an alias to CURLOPT_PROGRESSDATA */
curl_easy_setopt(curl,CURLOPT_XFERINFODATA,&prog);
#endif
curl_easy_setopt(curl,CURLOPT_nopROGRESS,0L);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr,"%s\n",curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
return (int)res;
}