C++ 使用 libcurl 实现文件下载
libcurl 是 C/C++ 中最常用的网络传输库,支持 HTTP/HTTPS/FTP 等协议下载文件。下面给你完整可直接运行的文件下载代码,包含断点续传、进度显示、错误处理。
一、准备工作
-
安装 libcurl
-
Windows:官网下载编译好的库,或用 vcpkg
-
Linux:sudo apt-get install libcurl4-openssl-dev
-
macOS:brew install curl
-
编译命令
Linux/macOS:
g++ download.cpp -o download -lcurl
二、完整下载代码(推荐)
支持:
-
HTTPS/HTTP 下载 -
本地文件写入 -
下载进度打印 -
网络错误处理 -
断点续传(可选)
#include<iostream>#include<fstream>#include<curl/curl.h>using namespace std;// 进度回调函数:打印下载进度staticintprogress_callback(void* ptr, curl_off_t total_download, curl_off_t now_download,curl_off_t total_upload, curl_off_t now_upload) {if (total_download <= 0) return 0;// 计算百分比float percent = (float)now_download / total_download * 100.0f;printf("下载进度:%.2f%% (%lld/%lld 字节)\r",percent, (long long)now_download, (long long)total_download);fflush(stdout);return 0;}// 写文件回调函数:libcurl 收到数据后写入本地文件staticsize_twrite_data(void* ptr, size_t size, size_t nmemb, void* stream){ofstream* out = static_cast<ofstream*>(stream);size_t written = out->write((char*)ptr, size * nmemb).tellp();return written;}// 下载函数booldownload_file(constchar* url, constchar* save_path){CURL* curl = curl_easy_init();if (!curl) {cerr << "curl 初始化失败!" << endl;return false;}// 打开输出文件(二进制模式)ofstream out_file(save_path, ios::binary);if (!out_file.is_open()) {cerr << "无法创建文件:" << save_path << endl;curl_easy_cleanup(curl);return false;}// ========== libcurl 配置 ==========// 下载 URLcurl_easy_setopt(curl, CURLOPT_URL, url);// 忽略 SSL 证书验证(HTTPS 下载用,正式环境建议关闭)curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);// 设置写数据函数curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);curl_easy_setopt(curl, CURLOPT_WRITEDATA, &out_file);// 开启进度条curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);curl_easy_setopt(curl, CURLOPT_XFERINFODATA, nullptr);// 超时 30 秒curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);// 执行下载CURLcode res = curl_easy_perform(curl);// 检查结果if (res != CURLE_OK) {cerr << "\n下载失败:" << curl_easy_strerror(res) << endl;} else {cout << "\n下载完成!保存到:" << save_path << endl;}// 清理out_file.close();curl_easy_cleanup(curl);return res == CURLE_OK;}intmain(){// 初始化 libcurlcurl_global_init(CURL_GLOBAL_ALL);// 使用示例const char* url = "https://example.com/file.zip"; // 下载地址const char* save = "downloaded_file.zip"; // 保存路径download_file(url, save);// 清理全局环境curl_global_cleanup();return 0;}
三、核心功能说明
1. 关键回调函数
-
write_data:libcurl 收到数据后自动调用,负责写入本地文件
-
progress_callback:实时计算并打印下载百分比
2. 常用配置
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
四、进阶:断点续传(从已下载位置继续)
只需添加一行代码:
// 获取已下载文件大小long long local_size = 0;ifstream test_file(save_path, ios::binary | ios::ate);if (test_file.is_open()) {local_size = test_file.tellg();test_file.close();}// 设置从某个字节开始下载curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, (curl_off_t)local_size);
五、常见问题
-
HTTPS 下载失败
开启:
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); -
中文文件名乱码
Windows 下需要将路径转为宽字符,或使用 UTF-8 编码。
-
编译提示找不到 curl
Linux 链接
-lcurl,Windows 配置好 libcurl 库目录。
总结
-
代码可直接编译运行,支持 HTTP/HTTPS -
自带进度条和错误处理 -
可轻松扩展断点续传、多线程下载 -
跨平台:Windows/Linux/macOS 通用
夜雨聆风