//重写把数据读入上传数据流函数
size_t read_file(void* buff, size_t size, size_t nmemb, void* userp)
{
size_t sizes = fread(buff, size, nmemb, (FILE *)userp);
return sizes;
}
int HTTP_file::upload_file(const char* url, const char* file_name)
{
if ("" == url || "" == file_name)
{
std::cout << "url地址或文件名为空,操作失败!" << std::endl;
return -1;
}
CURLcode res; //easy_handle定义的一些错误码
//初始化libcurl
res = curl_global_init(CURL_GLOBAL_ALL);
if (res != CURLE_OK)
{
std::cerr << "init libcurl failed." << std::endl;
return -1;
}
//获取要上传的文件指针
FILE* r_file = fopen(file_name, "rb");
if (0 == r_file)
{
std::cerr << "the file /" " << file_name << " /"that you will read is not exist" << std::endl;
return -1;
}
CURL* easy_handle;
easy_handle = curl_easy_init();
if (0 == easy_handle)
{
std::cout << "get a easy_handle handle fail!" << std::endl;
fclose(r_file);
curl_global_cleanup();
curl_easy_cleanup(easy_handle);
return -1;
}
// 获取文件大小
fseek(r_file, 0, 2);
int file_size = ftell(r_file);
rewind(r_file);
curl_easy_setopt(easy_handle, CURLOPT_URL, url); //获取URL地址
curl_easy_setopt(easy_handle, CURLOPT_UPLOAD, TRUE); //告诉easy_handle是做上传操作
curl_easy_setopt(easy_handle, CURLOPT_READFUNCTION, &read_file); //调用重写的读文件流函数
curl_easy_setopt(easy_handle, CURLOPT_READDATA, r_file); //往read_file()函数中传入用户自定义的数据类型
curl_easy_setopt(easy_handle, CURLOPT_INFILE, r_file); //定位作为上传的输入文件
curl_easy_setopt(easy_handle, CURLOPT_INFILESIZE, file_size); //上传的字节数
//执行设置好的操作
res = curl_easy_perform(easy_handle);
//获取HTTP错误码
int HTTP_flag = 0;
curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE , &HTTP_flag);
//一般清理动作
fclose(r_file);
curl_global_cleanup();
curl_easy_cleanup(easy_handle);
std::cout << "操作本地文件:" << file_name << "; url:" << url << ".";
//检测HTTP错误码和执行操作结果
if ((0 != check_error(HTTP_flag)) || (CURLE_OK != res))
{
std::cout << "失败!" << std::endl;
return -1;
}
else
{
std::cout << "成功!" << std::endl;
return 0;
}
}
//WRITEFUNCTION回调函数的实现,在这里只做简单的处理
size_t process_data(void *buffer, size_t size, size_t nmemb, std::string& user_p)
{
user_p = (char*)buffer;
return nmemb;
}
const int FILE_EXIST = 200;
int down_file(const char* url, const char* down_file_name)
{
// 初始化libcurl
CURLcode return_code;
return_code = curl_global_init(CURL_GLOBAL_ALL);
if (CURLE_OK != return_code)
{
cerr << "init libcurl failed." << endl;
curl_global_cleanup();
return -1;
}
// 获取easy handle
CURL *easy_handle = curl_easy_init();
if (NULL == easy_handle)
{
cerr << "get a easy handle failed." << endl;
curl_easy_cleanup(easy_handle);
curl_global_cleanup();
return -1;
}
// 设置easy handle属性
return_code = curl_easy_setopt(easy_handle, CURLOPT_URL, url);
//设置回调函数
return_code = curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, &process_data);
//回调函数的额外参数
std::string connectx;
return_code = curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &connectx);
// 执行数据请求
return_code = curl_easy_perform(easy_handle);
//判断获取响应的http地址是否存在,若存在则返回200,400以上则为不存在,一般不存在为404错误
int retcode = 0;
return_code = curl_easy_getinfo(easy_handle, CURLINFO_RESPONSE_CODE , &retcode);
if (CURLE_OK == return_code && FILE_EXIST == retcode)
{
double length = 0;
return_code = curl_easy_getinfo(easy_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD , &length);
FILE *fp = fopen(save_name.c_str(), "wb+");
fwrite(connectx.c_str(), 1, length, fp); //返回实际写入文本的长度,若不等于length则写文件发生错误.
fclose(fp);
}
else
{
std::cout << "请求的文件不存在!" << std::endl;
curl_easy_cleanup(easy_handle);
curl_global_cleanup();
return -1;
}
// 释放资源
curl_easy_cleanup(easy_handle);
curl_global_cleanup();
return 0;
}