使用C++ curl下载文件时始终得到0KB空文件,求排查问题
C++ Curl下载文件生成空文件的排查与修复
问题描述
尝试用C++结合Curl下载文件,代码如下,但本该下载2000KB的文件实际得到0KB空文件:
#define CURL_STATICLIB #include <iostream> #include <string> #include <curl/curl.h> int main() { CURL *curl; FILE *fp; CURLcode res; std::string url = "https://rtk3dsf-lb01-1291588867.us-east-1.elb.amazonaws.com/api/rpgdownload?args=%7B%22ver%22:%22l.0.0.1%22,%22sid%22:28555,%22region%22:%22EUR%22,%22lang%22:%22en%22,%22token%22:%22Fqbt-EuVHsrOVeLwiVIrmXS.ck3Ph8MGH03DjKp5Q7uqYFL9CNAr9WVeyxgnHvYH6wE6RnvAtUkUMmas2N0Gj.Q**%22%7D"; char outfilename[FILENAME_MAX] = "game.dat"; curl = curl_easy_init(); if (curl) { fp = fopen(outfilename,"wb"); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fp); res = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(fp); } return 0; }
错误点分析
- CURLOPT_WRITEFUNCTION参数误用:这个选项要求传入符合
size_t (*)(char*, size_t, size_t, void*)签名的函数指针,但你直接传了FILE*类型的fp,导致Curl无法正确处理数据写入逻辑。如果要直接写入文件,只需设置CURLOPT_WRITEDATA为文件指针,CURLOPT_WRITEFUNCTION可以留空使用默认实现(默认适配fwrite)。 - 缺少Curl全局初始化:调用
curl_easy_init()前必须执行curl_global_init(CURL_GLOBAL_ALL)完成全局初始化,否则会出现未定义行为。 - 无关键步骤错误检查:没有判断
fopen是否成功(比如权限不足、路径无效会导致文件打开失败),也没检查curl_easy_perform的返回值,无法定位请求是否成功。
修正后的代码
#define CURL_STATICLIB #include <iostream> #include <string> #include <curl/curl.h> int main() { // 全局初始化Curl curl_global_init(CURL_GLOBAL_ALL); CURL *curl = nullptr; FILE *fp = nullptr; CURLcode res; std::string url = "https://rtk3dsf-lb01-1291588867.us-east-1.elb.amazonaws.com/api/rpgdownload?args=%7B%22ver%22:%22l.0.0.1%22,%22sid%22:28555,%22region%22:%22EUR%22,%22lang%22:%22en%22,%22token%22:%22Fqbt-EuVHsrOVeLwiVIrmXS.ck3Ph8MGH03DjKp5Q7uqYFL9CNAr9WVeyxgnHvYH6wE6RnvAtUkUMmas2N0Gj.Q**%22%7D"; char outfilename[FILENAME_MAX] = "game.dat"; curl = curl_easy_init(); if (curl) { // 检查文件是否成功打开 fp = fopen(outfilename, "wb"); if (!fp) { std::cerr << "无法打开文件: " << outfilename << std::endl; curl_easy_cleanup(curl); curl_global_cleanup(); return 1; } curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // 设置写入目标的文件指针 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); // 执行请求并检查结果 res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cerr << "Curl请求失败: " << curl_easy_strerror(res) << std::endl; } curl_easy_cleanup(curl); fclose(fp); } else { std::cerr << "无法初始化Curl" << std::endl; } // 全局清理 curl_global_cleanup(); return 0; }
内容的提问来源于stack exchange,提问作者Myth
相关产品推荐
相关产品推荐

