C#实现文件断点续传下载的方法

苏见山
苏见山
发布时间:2026-10-13| 3人浏览过
原创

本文介绍了如何利用 C# 中的 HttpWebRequest 和 FileStream 实现支持断点续传的下载功能。核心逻辑在于识别本地已存在文件的长度,并在发起 HTTP 请求时添加 Range 头以指定偏移量,从而实现从断点处继续下载。

核心原理与准备工作

断点续传的核心依赖于 HTTP 协议的 Range 请求头。客户端在检测到本地已有部分下载内容时,读取该文件的大小作为字节偏移量,通过设置 Request.AddRange(offset) 告知服务器只需发送从该位置开始的数据。服务端响应后,客户端将流数据以追加方式写入本地文件,而非覆盖重写,以此节省流量并支持中断恢复。

为实现此功能,主要依赖以下基础库:

  • System.Net:用于创建和管理 HTTP 请求 (HttpWebRequest)。
  • System.IO:用于处理文件流的读写 (FStream、StreamReader)。
  • System.Text:处理编码格式判断(如 UTF-8、Unicode 等)。

第1步:构建通用 HTTP 请求封装类

为了便于管理请求参数及复用 Range 设置逻辑,建议将网络请求封装为独立的静态工具类。

  1. 目的:统一创建带有特定起始位置偏移的 HTTP 请求实例。
  2. 入口/动作:定义一个名为 getWebRequest 的公共静态方法。
  3. 关键参数:
    - url: 目标下载链接。
    - lStartPos: 起始字节偏移量,即断点位置,默认为 0 表示从头下载。
  4. 操作细节:调用 HttpWebRequest.Create(url) 创建对象,随即执行 request.AddRange(lStartPos)。
using System;using System.Net;using System.IO;namespace simpleDemo{ class httpClient { /// <summary> /// 获取带Range参数的WebRequest /// </summary> public static HttpWebRequest getWebRequest(string url, int lStartPos) { HttpWebRequest request = null; try { request = (System.Net.HttpWebRequest)HttpWebRequest.Create(url); request.AddRange(lStartPos); // 设置断点续传的关键 } catch (Exception ex) { Console.WriteLine(ex.Message); } return request; } }}

此步骤确保了每次调用下载函数时,都能准确携带上一次的中断位置信息。

第2步:下载主流程与状态判断

下载过程需要判断文件是否存在。如果不存在,直接新建;如果存在,则需要进入续传逻辑。本示例采用了一个小技巧:始终先下载到一个带有特定后缀的临时文件(例如 .cdel),待下载全部完成后,再将其重命名为主文件名。

  1. 准备:设定远程 URL 和本地保存路径。
  2. 逻辑分支 A - 全新下载:
    - 若文件不存在,则调用下载逻辑,目标路径为 path + ".cdel"。
  3. 逻辑分支 B - 断点续传:
    - 若文件已存在,打开该文件获取当前长度 lStartPos。
  4. 获取总大小校验:发送 HEAD 或 GET 请求获取服务端的 Content-Length。
  5. 完成判定:比较 response.ContentLength 与 lStartPos。如果两者相等,说明本地文件已经是完整的,直接重命名完成退出,避免无效请求。
public static void simpleDownload(string url, string path){ HttpWebRequest request = httpClient.getWebRequest(url, 0); WebResponse response = null; // 以追加模式打开文件 FileStream writer = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write); long lStartPos = writer.Length; long currentLength = lStartPos; long totalLength = 0; if (File.Exists(path)) { // 检查断点状态 response = request.GetResponse(); long sTotal = response.ContentLength; // 如果当前大小等于总大小,视为已完成 if (sTotal == lStartPos) { close(writer); File.Move(path, path.Replace(PERSIST_EXP, "")); Console.WriteLine("下载完成!"); return; } // 重新获取针对当前位置的 Request request = httpClient.getWebRequest(url, (int)lStartPos); writer.Seek(lStartPos, SeekOrigin.Begin); response = request.GetResponse(); totalLength = response.ContentLength + lStartPos; } else { response = request.GetResponse(); totalLength = response.ContentLength; } // ... 后续读取流代码 }

第3步:流式读取与进度更新

这是实际数据传输的阶段。从响应的 Stream 中按块读取字节数组,并写入 FileStream。

  1. 输入:response.GetResponseStream() 和网络缓冲区 byte[]。
  2. 动作:在 while ((c = reader.Read(buff, 0, buff.Length)) > 0) 循环中不断读取。
  3. 记录:累加已读取字节数 currentLength += c,并调用 writer.Write() 写入磁盘。
  4. 进度显示:根据 currentLength 和 totalLength 计算百分比并打印控制台日志。
Stream reader = response.GetResponseStream();byte[] buff = new byte[1024];int c = 0;while ((c = reader.Read(buff, 0, buff.Length)) > 0) { currentLength += c; writer.Write(buff, 0, c); progressBar(currentLength, totalLength); writer.Flush();}

这一过程的稳定性对于大文件至关重要。频繁调用 Flush() 虽有助于实时落盘减少数据丢失风险,但在网络极慢时可能影响性能,可视情况调整缓冲策略。

第4步:收尾工作与重命名

当数据流读取完毕,需确保所有资源被正确释放,并将临时文件还原。

  1. 资源清理:关闭 reader、writer 和 response,防止句柄泄漏。
  2. 完整性校验:判断最终的 currentLength 是否等于预期的 totalLength。
  3. 文件更名:若一致,调用 File.Move(path, path.Replace(PERSIST_EXP, "")) 去除后缀,正式生效。
close(writer); // 释放 writer 资源if (currentLength == totalLength) { File.Move(path, path.Replace(PERSIST_EXP, "")); Console.WriteLine("下载完成!");}else { Console.WriteLine("下载失败!");}

辅助功能:文件编码检测

虽然主要用于文本分析,但原代码中包含了一段通过检测文件前缀字节 (BOM) 来判断文本编码的逻辑。这涉及到对 byte 数组的前几个字节进行比对:

  • 0xEF, 0xBB, 0xBF -> UTF-8
  • 0xFF, 0xFE -> Unicode (UTF-16 LE)
  • 0xFE, 0xFF -> BigEndianUnicode (UTF-16 BE)

这段代码通过 stream.ReadByte() 逐位读取并转换,展现了如何在缺乏显式声明时底层探查数据属性。

总结与排错

要实现稳健的断点续传,除了正确使用 Range 头和追加写入外,还需注意以下几点:

  • 服务端支持度:某些特殊的 CDN 或代理服务器可能不支持 Range 请求,导致 AddRange 报错或失效。
  • 异常捕获:在网络中断时,务必处理好 SocketException 或 WebException,保留好中间状态文件。
  • 并发控制:同一文件不应同时启动多个相同路径的下载进程,否则会导致锁冲突或逻辑混乱。

以上就是 C# 实现文件断点续传下载的详细内容,更多关于 C# 网络编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。