一、基础概念(必考)
1. 客户端与服务端
客户端:请求数据的一端(本机程序)
服务端:提供资源、响应请求的一端(云端服务器)
2. HTTP 协议与工具类
HttpClient:.NET 官方 HTTP 请求客户端,专门用于网络上传、下载、接口请求
URL:资源网络地址(完整访问地址)
URI:URL 转换后的统一资源唯一标识,程序请求必须使用 URI 对象
3. 三种 HTTP 请求方式(本案例核心)
HEAD:只请求响应头,只获取文件信息(大小、类型),不下载内容、速度极快
GET:请求服务器资源正文,用于真正下载文件数据
POST:向服务器提交数据(本案例未使用)
二、核心功能介绍
本项目实现完整工业级下载功能:
自定义保存路径(文件夹选择器)
分片下载:大文件分块分批下载,避免一次性加载内存溢出
断点续传:暂停/关闭程序后,再次下载自动从已下载位置接续,不重复下载
任务取消:基于 CancellationTokenSource 安全终止下载
实时进度更新:进度条 + 百分比文本实时刷新
按钮状态锁定(防止重复点击冲突)
三、核心技术原理详解
1. 断点续传原理
下载前判断本地文件是否存在
存在:读取本地文件现有长度,作为下次下载的起始位置
通过Range 请求头告诉服务器:从指定字节位置继续返回数据
文件流使用Append 追加模式,保留已有数据,续写新数据
2. 分片下载原理
将超大文件切分为 1000 字节小分片
循环请求每一段分片数据、逐段写入本地
解决一次性读取超大文件导致的内存溢出、卡顿问题
3. RangeHeaderValue 核心
RangeHeaderValue(start,end):限定本次请求的文件字节范围,是分片/断点下载的核心请求头
4. 取消机制
使用CancellationTokenSource令牌,安全终止 HttpClient 请求与循环,杜绝强行终止导致的文件损坏、线程卡死。
四、完整代码分层解析
1. 全局对象定义
// 全局唯一HTTP请求客户端(推荐全局静态,避免频繁创建销毁) public static readonly HttpClient httpClient = new HttpClient(); // 取消令牌:控制下载终止 public CancellationTokenSource cts;2. 选择保存路径
通过 FolderBrowserDialog 选择文件夹,赋值给文本框,作为文件保存根目录。
3. 下载按钮核心逻辑
非空校验:必须设置保存路径、资源URL
锁定界面按钮,防止重复点击
新建取消令牌
Task.Run 开启后台下载(不卡死UI)
ContinueWith 回调:下载完成解锁界面、提示完成
4. 核心 Download 下载方法(重点)
第一步:HEAD 请求获取文件总大小
使用 HEAD 方式请求,只读取响应头 ContentLength,获取服务器文件真实大小,不下载内容,高效快速。
第二步:判断本地文件,实现断点续传
文件不存在:startPosition=0,从头创建下载
文件存在:读取已有长度,从当前位置续写
已下载完整:直接抛出异常“文件已下载完成”
第三步:分片循环下载
固定分片大小 1000 字节
设置 Range 分段请求头
GetAsync 获取分段数据
文件流追加写入
更新下载位置、刷新UI进度
5. 取消下载逻辑
cts.Cancel()触发取消信号,循环检测IsCancellationRequested终止下载,重置所有界面状态。
6. 简单 Get 接口请求演示
通过 GetAsync 直接请求网页接口,读取字符串返回结果,适用于普通接口调用。
五、必考知识点总结
HEAD 与 GET 区别:HEAD拿文件信息,GET拿文件内容
断点续传核心:判断本地文件长度 + Range请求头 + 文件追加模式
分片下载核心:切割字节范围,循环分段请求,防止内存溢出
异步不卡UI:Task.Run 后台执行耗时下载,Invoke 更新界面
安全取消任务:CancellationToken 优雅终止,杜绝暴力终止报错
URI 作用:将URL字符串转为程序可识别的统一资源对象
HttpClient 规范:全局静态单例使用,不重复 new,避免端口耗尽
六、代码易错点
下载属于耗时操作,必须放子线程,直接主线程下载会卡死UI
更新进度条、文本必须 Invoke,子线程不能直接操作UI
每次下载必须new 新的 CancellationTokenSource,令牌不可复用
文件结尾分片需要判断边界,防止 end 超出总文件大小
断点续传必须使用 FileMode.Append 追加模式