libcurl实现断点续传

实现断点续传主要就是通过curl_easy_setopt设置好CURLOPT_RESUME_FROM_LARGE属性完成

首先获取已下载文件大小,然后设置CURLOPT_RESUME_FROM_LARGE属性,从指定字节开始下载

#include <sys/stat.h>
// Get the local file size,return -1 if failed
_off_t getLocalFileLength(string path)
{
	_off_t ret;
	struct stat fileStat;

	ret = stat(path.c_str(), &fileStat);
	if (ret == 0)
	{
		return fileStat.st_size;
	}

	return ret;
}

curl_off_t resumeByte = getLocalFileLength("test10.zip"); // 本地已下载文件的字节大小,确保resumeByte类型为curl_off_t(Windows平台为long long,Mac为long)否则容易出错
int ret = curl_easy_setopt(easy_handle, CURLOPT_RESUME_FROM_LARGE, resumeByte);

resumeByte的类型不对或者超过了服务器文件的Content-Length时,curl_easy_perform都会返回错误

下次开始时,将会从指定的字节位置开始下载。

计算下载进度时需要注意一点,dltotal得到的不是服务器上文件的大小,而是还需要下载字节的大小,也就是说dototal并不是test10.zip这个文件的大小,而是test10.zip的大小减去本地已经下载的大小。

那么如何得到服务器上的文件大小,我们可以通过libcurl发送请求header,返回的Content-Length就是文件大小

// 获取服务器上的文件大小
double getDownloadFileLength(string url)
{
	CURL *easy_handle = NULL;
	int ret = CURLE_OK;
	double size = -1;

	do
	{
		easy_handle = curl_easy_init();
		if (!easy_handle)
		{
			printf("easy_handle init error\n");
			break;
		}

		// 仅获取HTTP头
		ret = curl_easy_setopt(easy_handle, CURLOPT_URL, url.c_str());
		ret |= curl_easy_setopt(easy_handle, CURLOPT_HEADER, 1L);
		ret |= curl_easy_setopt(easy_handle, CURLOPT_NOBODY, 1L);

		if (ret != CURLE_OK)
		{
			break;
		}

		ret = curl_easy_perform(easy_handle);
		if (ret != CURLE_OK)
		{
			break;
		}

		// 没有查询到的话size=-1
		ret = curl_easy_getinfo(easy_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size);
		if (ret != CURLE_OK)
		{
			break;
		}
	} while (0);
	
	curl_easy_cleanup(easy_handle);
	return size;
}

整个工程的GitHub地址:https://github.com/forzxy/HttpClient


  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值