我使用curl进行上传和下载,并尝试在curl中包含提供的进度条。我设法在上传文件时使进度条工作,但不幸的是回调函数只在下载时收到0值。
以下是为下载设置的选项:
::curl_easy_reset( m_pimpl->curl ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_SSL_VERIFYPEER, 0L ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_SSL_VERIFYHOST, 0L ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADERFUNCTION, &CurlAgent::HeaderCallback ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADERDATA, this ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADER, 0L ) ;
::curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method.c_str() ); // "GET" in download
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error ) ;
::curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlAgent::Receive ) ;
::curl_easy_setopt(curl, CURLOPT_WRITEDATA, this ) ;
//setting the progress callback function
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this);
CURLcode curl_code = ::curl_easy_perform(curl);
这是用于进度条的回调:
static int progress_callback(void *ptr, curl_off_t TotalDownloadSize, curl_off_t finishedDownloadSize, curl_off_t TotalToUpload, curl_off_t NowUploaded) {
curl_off_t processed = (TotalDownloadSize > TotalToUpload) ? finishedDownloadSize : NowUploaded;
curl_off_t total = (TotalDownloadSize > TotalToUpload) ? TotalDownloadSize : TotalToUpload;
...
return 0;
}
如上所述,当我执行文件上传时,参数TotalToUpload
和NowUploaded
包含正确的值。但是当下载所有四个参数包含0
时!
下载文件时是否必须设置其他选项才能获得正确的尺寸?
替代解决方案
我找到了另一种解决方案,使用另一个请求购买,该请求提供有关驱动器上文件的信息,该文件也包含文件大小。 在set回调写函数
中 ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlAgent::Receive )
当前下载的大小作为参数给出,然后可以创建进度条。
Here也是使用过的服务和请求的文档:
答案 0 :(得分:1)
根据libcurl文档:
CURLOPT_XFERINFOFUNCTION explained
传递给回调的未知/未使用的参数值将设置为零(就像您只下载数据一样,上传大小将保持为0)。 很多时候,在它知道数据大小之前,首先会调用一次或多次回调,因此必须使程序处理它。
如果回调是从不在下载过程中给你非零值,那么:
libcurl中存在一个错误(不太可能)
libcurl 根本不知道大小(更有可能),例如下载是否以无法有效计算大小的方式编码。