C++ Windows环境下实现文件下载的两种方法
本文介绍在C++中如何通过Windows API实现文件下载,涵盖基于URLDownloadToFile的简单调用和基于WinInet库的手动读写方案,包含完整代码示例。
结果或目标
在Windows平台下,使用C++将远程HTTP资源下载到本地指定路径。本文将展示两种典型的实现路径:直接下载法和流式读写法。
准备条件
- 操作系统:Windows
- 开发环境:支持MFC或标准Windows API编译的C++项目(如Visual Studio)
- 依赖库:
UrlMon.lib和WinInet.lib
真实操作顺序
第1步:引入必要头文件与链接库
目的:加载Windows下载功能所需的API声明。
- 入口:源文件顶部
- 动作:添加头文件引用并链接静态库。
- 重要参数:
- #include
<UrlMon.h> - #include
<WinInet.h> - #pragma comment(lib,
"wininet") // 链接WinInet库
第2步:方法一 - 使用 URLDownloadToFile 快速下载
目的:最简单的方式下载单个文件,适合无需复杂Header控制的场景。
- 入口:触发下载的函数(如按钮点击事件)
- 动作:调用
URLDownloadToFile函数。 - 重要参数:
- pCaller: NULL(通常传空)
- szURL: 远程下载地址字符串
- szFileName: 本地保存路径(需确保目录存在)
- reserved: 0
- pfnCB: NULL(不使用回调)
- 完成状态:返回值等于
S_OK表示成功,否则失败。
void DownloadSimple() {
HRESULT hRet = URLDownloadToFile(
NULL,
"http://www.baidu.com/img/baidu_sylogo1.gif",
"c:\\temp\\1.gif",
0,
NULL
);
if (S_OK != hRet) {
MessageBox(NULL, _T("下载失败"), _T("Error"), MB_ICONERROR);
return;
}
MessageBox(NULL, _T("下载成功"), _T("Success"), MB_ICONINFORMATION);
}
第3步:方法二 - 使用 WinInet 库手动读写
目的:需要自定义请求头、代理设置或处理大文件时的通用方案。
- 入口:触发下载的函数
- 动作:依次打开会话、打开URL、循环读取数据、写入文件、关闭句柄。
- 关键步骤:
- 初始化会话:调用
InternetOpen。
- agentName: 用户代理标识
- dwAccessType:INTERNET_OPEN_TYPE_PRECONFIG(使用系统代理配置) - 打开URL:调用
InternetOpenUrl。
- 注意设置标志位如INTERNET_FLAG_DONT_CACHE避免本地缓存干扰。 - 读取与写入:创建本地文件句柄
fopen,使用while循环配合InternetReadFile和fwrite。
- 缓冲区大小:例如 1024字节
- 读取数量:dwNum - 清理资源:必须按逆序关闭文件和Internet句柄,防止内存泄漏。
void DownloadWithWinInet() {
// 1. 初始化Internet会话
HINTERNET hSession = InternetOpen(
"MyApp/1.0",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, 0
);
if (!hSession) return;
// 2. 打开URL
HINTERNET hLink = InternetOpenUrl(
hSession,
"http://www.baidu.com/img/baidu_sylogo1.gif",
NULL, 0,
INTERNET_FLAG_RELOAD,
0
);
if (!hLink) {
InternetCloseHandle(hSession);
return;
}
// 3. 创建本地文件用于接收数据
FILE* hFile = fopen("c:\\temp\\2.gif", "wb");
if (!hFile) {
InternetCloseHandle(hLink);
InternetCloseHandle(hSession);
return;
}
// 4. 循环读取并写入
BYTE temp[1024];
DWORD dwNum = 1; // 初始设为非0以进入循环
while (dwNum > 0) {
// 尝试读取数据
if (!InternetReadFile(hLink, temp, sizeof(temp), &dwNum)) {
break; // 发生错误则退出
}
// 如果有数据,写入文件
if (dwNum > 0) {
fwrite(temp, sizeof(char), dwNum, hFile);
}
}
// 5. 清理资源
fclose(hFile);
InternetCloseHandle(hLink);
InternetCloseHandle(hSession);
MessageBox(NULL, _T("download finished..."), _T("Info"), MB_ICONINFORMATION);
}
完成判断
- 方法一:检查
URLDownloadToFile返回值是否为S_OK。 - 方法二:循环中
dwNum最终变为 0 且无错误发生,本地文件大小与预期一致。
简要总结
C++在Windows下进行文件下载主要依赖系统级API。URLDownloadToFile 适合极简场景,而 WinInet 提供了更细粒度的控制能力,适用于需要认证、代理或进度监控的复杂应用。在实际项目中,请确保目标目录存在,并注意关闭所有打开的句柄以避免资源泄露。以上就是C++实现文件下载的详细内容,更多关于C++网络编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









