C++实现文件下载功能

bool DownLoad(LPCWSTR _url, QString strfile)
{
	QByteArray arr = strfile.toLocal8Bit();
	const char* _file_name = arr.data();
	FILE* fp_download = fopen(_file_name, "wb");
	if (fp_download == NULL)
	{
		return false;
	}

	HINTERNET innet_open = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
	if (innet_open == NULL)
	{
		fclose(fp_download);
		return false;
	}


	HINTERNET innet_url = InternetOpenUrl(innet_open, _url, NULL, 0, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_PRAGMA_NOCACHE, 0);
	if (innet_url == NULL)
	{
		InternetCloseHandle(innet_url);
		return false;
	}

	//检查状态码
	DWORD http_status;
	DWORD http_status_size = sizeof(http_status);
	HttpQueryInfo(innet_url, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &http_status, &http_status_size, NULL);
	if (http_status != 200)
	{
		InternetCloseHandle(innet_url);
		InternetCloseHandle(innet_open);
		return false;
	}

	//获取接收数据大小
	DWORD file_length = 0;
	DWORD file_length_size = sizeof(file_length);
	HttpQueryInfo(innet_url, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &file_length, &file_length_size, NULL);
	if (file_length < 0)
	{
		InternetCloseHandle(innet_url);
		InternetCloseHandle(innet_open);
		return FALSE;
	}

	DWORD res_len = 1;
	DWORD read_len = 0;
	uint8_t temp_buf[DOWNLOAD_BUFFER_SIZE] = { 0 };
	while (true)
	{
		memset(temp_buf, 0, sizeof(uint8_t) * res_len);
		InternetReadFile(innet_url, temp_buf, DOWNLOAD_BUFFER_SIZE, &res_len);
		if (res_len <= 0)
			break;
		if (res_len == fwrite(temp_buf, sizeof(uint8_t), res_len, fp_download))
		{
			read_len += res_len;
		}
	}


	InternetCloseHandle(innet_url);
	InternetCloseHandle(innet_open);
	fclose(fp_download);

	return true;
}
void main()
{
	if(true == DownLoad(L"https://eval.zhihuiyunji.com/riskclient_update/", fileName)
	{
		//下载成功就解析文件,读取内容
	}
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
实现根据下载链接下载文件,可以从链接中解析出主机名、文件路径等信息,然后根据这些信息使用Socket编程库来下载文件。 以下是一个简单的示例代码,实现根据下载链接下载文件的功能: ```c++ #include <iostream> #include <fstream> #include <winsock2.h> #include <regex> #pragma comment(lib, "ws2_32.lib") int main() { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); std::string downloadUrl = "https://example.com/file/path"; // 要下载的文件的链接 std::regex urlRegex("(https?)://([^/]+)(.*)"); // 正则表达式,用于解析链接中的主机名和文件路径 std::smatch matchResult; if (!std::regex_match(downloadUrl, matchResult, urlRegex)) { std::cerr << "Invalid URL." << std::endl; return 1; } std::string protocol = matchResult[1]; // 协议,http 或 https std::string hostname = matchResult[2]; // 主机名 std::string filepath = matchResult[3]; // 文件路径 SOCKET sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sockfd == INVALID_SOCKET) { std::cerr << "Failed to create socket." << std::endl; return 1; } sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(protocol == "https" ? 443 : 80); // 根据协议选择端口号 serverAddr.sin_addr.s_addr = inet_addr(hostname.c_str()); if (connect(sockfd, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { std::cerr << "Failed to connect to server." << std::endl; return 1; } std::string request = "GET " + filepath + " HTTP/1.1\r\nHost: " + hostname + "\r\nConnection: close\r\n\r\n"; // 构造 HTTP 请求头 send(sockfd, request.c_str(), request.length(), 0); char buffer[1024]; std::ofstream file("downloaded_file"); // 下载的文件保存在本地的文件名 int bytesReceived; while ((bytesReceived = recv(sockfd, buffer, 1024, 0)) > 0) { file.write(buffer, bytesReceived); } file.close(); closesocket(sockfd); WSACleanup(); return 0; } ``` 需要注意的是,本示例代码仅适用于HTTP和HTTPS协议的文件下载,如果需要下载其他类型的文件或者使用其他协议进行下载,需要根据实际情况进行调整。同时,本示例代码中还需要添加一些异常处理的代码,以确保程序的稳定性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值