c语言http文件下载断点续传示例(libcurl)
Published on 2023-03-15 14:19 in 分类: C/C++ with 萧海~
分类: C/C++

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

    以下是 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() 函数以进行断点续传。

    posted @   萧海~  阅读(834)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · winform 绘制太阳,地球,月球 运作规律
    · AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
    · 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
    · 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
    · 上周热点回顾(3.3-3.9)
    历史上的今天:
    2021-03-15 MFC 设置程序固定窗口大小
    2021-03-15 C++调用MATLAB函数
    2021-03-15 C++无名命名空间详解
    2021-03-15 并发编程: c++11 thread(Func, Args...)利用类成员函数创建线程
    2021-03-15 并发编程:c++11 多线程中随机数重复问题
    点击右上角即可分享
    微信分享提示
    电磁波切换