首页 > 其他分享 >c语言http文件下载断点续传示例(libcurl)

c语言http文件下载断点续传示例(libcurl)

时间:2023-03-20 14:02:53浏览次数:70  
标签:http 示例 libcurl bytes easy handle curl 下载 size

以下是 C 语言实现 HTTP 文件下载的断点续传示例代码。假设要下载的文件 URL 为 ​​http://example.com/example.zip,本地保存为​​ example.zip。

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

#define LOCAL_FILE_NAME "example.zip"
#define REMOTE_FILE_URL "http://example.com/example.zip"

/* 用于记录已下载的字节数 */
static long long download_bytes = 0;

/* 将下载的数据写入本地文件 */
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
FILE *fp = (FILE *)stream;
size_t written = fwrite(ptr, size, nmemb, fp);
download_bytes += written;
return written;
}

int main(void) {
CURL *curl_handle;
FILE *local_fp;
char range_header[64];

/* 创建一个 CURL 对象 */
curl_handle = curl_easy_init();

/* 打开本地文件,以二进制方式追加写入 */
local_fp = fopen(LOCAL_FILE_NAME, "ab");
if (!local_fp) {
fprintf(stderr, "Error: cannot open file \"%s\"\n", LOCAL_FILE_NAME);
return 1;
}

/* 设置 CURL 的一些参数 */
curl_easy_setopt(curl_handle, CURLOPT_URL, REMOTE_FILE_URL); // 设置 URL
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); // 自动跳转
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback); // 设置回调函数
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, local_fp); // 设置回调函数的参数

/* 如果断点续传,设置 Range 头部信息 */
if (download_bytes > 0) {
snprintf(range_header, sizeof(range_header), "Range: bytes=%lld-", download_bytes);
curl_easy_setopt(curl_handle, CURLOPT_RANGE, range_header);
}

/* 执行 HTTP 请求 */
CURLcode res = curl_easy_perform(curl_handle);

/* 检查是否出错 */
if (res != CURLE_OK) {
fprintf(stderr, "Error: %s\n", curl_easy_strerror(res));
}

/* 获取下载的文件大小 */
double file_size;
curl_easy_getinfo(curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &file_size);

/* 关闭本地文件和 CURL */
fclose(local_fp);
curl_easy_cleanup(curl_handle);

/* 输出下载的结果 */
if (download_bytes == file_size) {
printf("Download completed!\n");
} else if (download_bytes > 0 && download_bytes < file_size) {
printf("Download interrupted (downloaded %lld bytes, file size is %.0f bytes). Resume downloading...\n", download_bytes, file_size);
main(); // 递归调用自己以断点续传
} else {
printf("Download failed!\n");
}

return 0;
}

注意:

在每次下载前,需要读取本地文件大小,判断是否需要进行断点续传(即是否已经下载了一部分文件)。
如果需要进行断点续传,需要设置 Range 头部信息。Range 头部指定从哪个字节开始下载。
在回调函数中,需要记录已下载的字节数,并将下载的数据写入本地文件。注意,在追加写入时,需要使用 "ab" 模式打开本地文件并在最后追加写入。
如果下载未完成(即已下载的字节数小于文件大小),需要递归调用 main() 函数以进行断点续传。



标签:http,示例,libcurl,bytes,easy,handle,curl,下载,size
From: https://blog.51cto.com/xiaohaiwa/6132725

相关文章

  • 接口自动化测试必备技能——HTTP协议(九)
    1.HTTP协议简介及状态码解析HTTP协议简介HTTP协议,中文名称为超文本传输协议它是一个应用层的协议,私有请求和响应构成其典型的引用场景就是浏览器和服务器之间进行......
  • https://www.cursor.so/
    Cursor|BuildFast GPT-4自动写代码刚刚发布的Cursor编辑器集成了GPT-4接口,我测试了下他生成代码的能力,叹为观止,我尝试了从前端到后段,从纯软到软硬结合,从UE到U......
  • Vue插件:Vue-resource github搜索示例
     1:安装插件  vue-resourcevue的插件库,在vue1.0年代使用几率很高......
  • php线程安全(TS)和非线程(NTS)安全区别 本文来源:码农网 本文链接:https://www.coderct
    以下线程安全简称TS非线程安全简称NTS首先unix/linux不强调使用线程模型,强调使用多进程模型,windows下面才强调使用多线程。创建进程的速度比创建线程慢几倍,并且相互通信......
  • WebDataBinder与HttpMessageConverter
    HttpMessageConverter​​HttpMessageConverter<T>​​是Spring3.0新添加的一个接口,负责将请求信息转换为一个对象(类型为T),将对象(类型为T)输出为响应信息//指定转换器可......
  • SQL Server交叉表应用示例
    说明一、建立表主要有三列列:FeeDeptID(科室编号),ItemiD(项目编号),金额FeeDeptID,ItemiD关联其他表二、创建存储过程CreatePROCEDURE存储过程1@fromDatedate, @ToDate......
  • 给你清清楚楚讲明白HTTPS原理
    为什么用了HTTPS就是安全的?HTTPS的底层原理如何实现?用了HTTPS就一定安全吗?HTTPS的实现原理大家可能都听说过HTTPS协议之所以是安全的,是因为HTTPS协议会......
  • Go 每日一库 GitHub:https://github.com/darjun/go-daily-lib
    简介今天我们介绍一个合并结构体字段的库mergo。mergo可以在相同的结构体或map之间赋值,可以将结构体的字段赋值到map中,可以将map的值赋值给结构体的字段。感谢@thinkgos推......
  • HttpMessageConverter
    一、HttpMessageConverter<T>1、HttpMessageConverter简介HttpMessageConverter<T> 是 Spring3.0 新添加的一个接口,负责将请求信息转换为一个对象(类型为 T......
  • HTTP 状态码
    状态码状态码是来告诉客户端,发生了什么事情。状态码为客户端提供了一种理解事务处理结果的便捷方式。状态码位于响应的起始行中比如,在行HTTP/1.0200OK中,状态码就是2......