跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

c#如何实现断点续传上传_c#断点续传上传完整教程与实战案例

断点续传的核心是“校验+分块+记录”,而非简单重传;需客户端分块、存进度、跳过已传块,服务端提供分片上传与合并校验接口,并保障幂等性与状态一致性。 断点续传的核心不是“重传”,而是“校验+分块+记录” 断点续传上传在 C# 中没有现成的
UploadWithResume()
一键方法。它本质是客户端主动管理文件切片、服务端配合校验已传片段、双方通过唯一标识(如文件 hash 或分片编号)确认进度。强行用
WebClient
或简单
HttpClient.PostAsync()
直传整个文件,失败后只能从头再来——这不是断点续传,只是“重试”。 客户端必须自己分块并记录上传状态到本地 关键动作不在网络库,而在你如何切文件、存进度、跳过已传块。常见错误是把“上传失败后重新调用同一方法”当成续传,结果重复发了全部数据。 用
FileStream
+
BufferedStream
按固定大小(如 4MB)读取文件块,避免一次性加载大文件进内存 每块生成唯一标识:推荐
fileHash + chunkIndex
(不要只用
chunkIndex
,防止不同文件冲突) 上传前先查本地状态文件(如
upload_state.json
),读取已成功上传的
chunkIndex
列表 只对未上传或校验失败的块发起请求;上传成功后立即追加写入该
chunkIndex
到状态文件(建议用
File.AppendAllText()
+ 行式存储,避免并发写损坏) 服务端需提供两个最小接口:分片上传 + 合并校验 ASP.NET Core 中,别指望
IFormFile
能直接处理分片——它默认等待整个 multipart body 完整才触发绑定,超时或中断就全丢。必须手动解析 raw request body。 C知道 CSDN推出的一款AI技术问答工具 下载
POST /api/upload/chunk
:接收
multipart/form-data
,提取
file_hash
、
chunk_index
、
total_chunks
和二进制块。保存路径建议为
./uploads/{file_hash}/{chunk_index}
POST /api/upload/merge
:收到所有块后,按序拼接并计算最终文件 hash,与客户端传来的
file_hash
对比;一致才写入正式目录,否则返回 400 并清空临时块 注意:上传块接口必须支持幂等(相同
file_hash + chunk_index
多次提交应视为一次成功),避免网络重发导致块重复写入 HttpClient 不要复用默认实例做分块上传 用全局单例
HttpClient
发大量小块请求,容易触发连接池耗尽或 TIME_WAIT 爆满。尤其在 Windows 上,默认连接数限制低(如 .NET 6 默认 10),上传 100 块就卡住。 为每个文件上传新建一个
HttpClient
实例(配合
using
),或至少按上传任务隔离连接池:
new SocketsHttpHandler { MaxConnectionsPerServer = 32 }
给每个分块请求显式设置超时:
client.Timeout = TimeSpan.FromMinutes(5)
(不能依赖全局 Timeout) 禁用自动重定向:
client.DefaultRequestHeaders.ExpectContinue = false
,避免分块请求被中间代理误判 别用
MultipartFormDataContent
包裹每个块——它会额外加 boundary 开销。直接用
ByteArrayContent
+ 手动构造 header 更轻量 真正难的不是代码怎么写,而是状态一致性:客户端认为某块传完了,服务端因磁盘满没写入,但返回了 200;或者合并时发现少一块,却找不到是哪边丢了日志。务必在每一步加可追溯的 traceId,并让客户端和服务端都记录
file_hash
、
chunk_index
、
bytes_sent
、
http_status
四元组。

相关文章