C#断点续传下载。
断点续传
最近在优化之前的下载流程,仅此篇幅留作笔记之用,日后其他研究此类问题的伙伴可以马上了解原理和开发,减少开发成本。
原理:断点续传目前比较通用的是使用HTTP续传方式,相关的资料可以通过访问:这边简单的说明下--HTTP是(超文本传输协议),而HTTP又是基于TCP/IP协议之上的协议,好了这边我们不需要了解的太深,知道它是超文本传输协议就好了,即维系(服务器Server)和(客户端Client)之间的传输协议;
思路:通过超链接(可以是你的FTP服务器或者任意的可访问地址)下载然后本地文件根目录(最终目标保存)进行保存。中间的方式采用超文本传输协议(HTTP)完成;
1-首先定义一个临时文件格式PERSIST_EXP,用于保存已经下载的临时文件;
/// <summary> /// temporary file byte /// </summary> public static string PERSIST_EXP = ".cdel";
2-更新下载的核心方法;
public void download(string url, string path) { if (File.Exists(path)) { if (MessageBox.Show("文件己存在!是否重新下载?", "Confirm Message", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK) { File.Delete(path);//先删除后重新下载 ResumeDownload(url, path); } else return; } else { //续传 ResumeDownload(url, path); } } private void ResumeDownload(string url, string path) { path = path + PERSIST_EXP; simpleDownload(url, path);//开始下载 }
3-续传核心方法:使用HttpWebRequest类从客户端发送URL(这个URL就是服务器地址)给服务器请求响应,然后服务器返回一个Request信息。具体的HttpWebRequest介绍可以访问:https://msdn.microsoft.com/zh-cn/library/system.net.httpwebrequest.aspx。 然后通过WebResponse进行资源的响应获取真正的源信息。接下来就是随心所欲的操作了。
HttpWebRequest request = getWebRequest(url, 0); WebResponse response = null; response = request.GetResponse(); totalLength = response.ContentLength; Stream reader = response.GetResponseStream(); await Task.Run(() => UpdateProcess(reader, currentLength, writer, totalLength, path, response));//开辟一条新的进程,用于执行任务,主线程直接结束;
4-通过字节逐个读取并写入临时文件;(其中需要注意的是字节reader对象、writer对象、还有响应的response读取完成之后需要清除和释放)
private void UpdateProcess(Stream reader, long currentLength, FileStream writer, long totalLength, string path, WebResponse response) { byte[] buff = new byte[1024]; int c = 0; //实际读取的字节数 while ((c = reader.Read(buff, 0, buff.Length)) > 0) { currentLength += c; writer.Write(buff, 0, c); this.Dispatcher.Invoke(() => progressBar(currentLength, totalLength));//进度条 writer.Flush(); } close(writer); if (currentLength == totalLength) { File.Move(path, path.Replace(PERSIST_EXP, "")); MessageBox.Show("下载完成!"); } if (reader != null) { reader.Close(); reader.Dispose(); response.Close(); } }
5- 还未下载完成然后断开,第二次启动的时候就需要检索当前的字节读取范围以及剩下的字节还有多少需要读取,保证读取的完整性;
request = getWebRequest(url, (int)lStartPos);//设置Range值 writer.Seek(lStartPos, SeekOrigin.Begin);//指针跳转 response = request.GetResponse(); totalLength = response.ContentLength + lStartPos; //总长度 currentLength = lStartPos; //当前长度
工作的事情要做就要做到最好,做到极致,做到无人能及。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?