现在的位置: 首页 > 综合 > 正文

libcurl http download upload

2018年05月08日 ⁄ 综合 ⁄ 共 3111字 ⁄ 字号 评论关闭
	//重写把数据读入上传数据流函数
	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;
}

抱歉!评论已关闭.