如何使用FtpWebRequest恢复中断的FTP下载
用FtpWebResponse实现FTP断点续传的可行方案
你遇到的问题很典型:FtpWebResponse返回的响应流是只读、单向的网络流,本身不支持Seek操作,所以直接调用Seek肯定会报错。不过咱们完全可以借助FTP协议的REST(Restart)命令,用标准的.NET类实现断点续传,具体步骤如下:
1. 确定续传起始位置
首先检查本地已下载的不完整文件大小,这个数值就是我们要告诉服务器的续传起点:
long resumePosition = 0; string localSavePath = @"D:\Downloads\large_file.iso"; // 如果本地已有中断的下载文件,获取其长度 if (File.Exists(localSavePath)) { using (var fileStream = new FileStream(localSavePath, FileMode.Open, FileAccess.Read)) { resumePosition = fileStream.Length; } }
2. 配置FtpWebRequest启用续传
创建FTP请求时,通过ContentOffset属性设置续传起始位置——这个属性本质上就是帮你向服务器发送REST命令,不用手动拼接协议指令:
var ftpRequest = (FtpWebRequest)WebRequest.Create("ftp://your-ftp-server.com/large_file.iso"); ftpRequest.Credentials = new NetworkCredential("your-username", "your-password"); ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; // 关键:设置续传的起始字节位置 ftpRequest.ContentOffset = resumePosition;
3. 下载并追加到本地文件
拿到响应流后,不要覆盖本地文件,而是以FileMode.Append的方式打开本地流,把服务器返回的字节追加到已有文件末尾:
try { using (var ftpResponse = (FtpWebResponse)ftpRequest.GetResponse()) using (var responseStream = ftpResponse.GetResponseStream()) using (var localFileStream = new FileStream(localSavePath, FileMode.Append, FileAccess.Write)) { byte[] buffer = new byte[8192]; // 用8KB缓冲区平衡速度和内存占用 int bytesRead; while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0) { localFileStream.Write(buffer, 0, bytesRead); } Console.WriteLine($"下载完成!总文件大小:{resumePosition + ftpResponse.ContentLength}字节"); } } catch (WebException ex) { // 处理网络异常,比如断开连接,下次启动时重复上述流程即可 Console.WriteLine($"下载中断:{ex.Message}"); }
额外注意事项
- 服务器兼容性:不是所有FTP服务器都支持
REST命令,你可以先发送FEAT命令检查服务器是否支持续传:var featRequest = (FtpWebRequest)WebRequest.Create("ftp://your-ftp-server.com/"); featRequest.Credentials = new NetworkCredential("your-username", "your-password"); featRequest.Method = "FEAT"; using (var featResponse = (FtpWebResponse)featRequest.GetResponse()) using (var reader = new StreamReader(featResponse.GetResponseStream())) { var serverFeatures = reader.ReadToEnd(); if (serverFeatures.Contains("REST STREAM")) { Console.WriteLine("当前FTP服务器支持断点续传"); } else { Console.WriteLine("当前FTP服务器不支持断点续传"); } } - 异常处理:网络不稳定时可能会再次中断,所以要做好异常捕获,下次启动下载时重复上述流程即可自动续传。
内容的提问来源于stack exchange,提问作者MiguelSlv
相关产品推荐
相关产品推荐

