《C# 文件下载四方法》
在.NET开发中,文件下载是常见的需求场景,无论是从本地路径读取文件还是从网络获取资源,都需要通过编程实现高效、安全的下载功能。本文将详细介绍四种C#中实现文件下载的核心方法,涵盖基础API调用、异步编程、第三方库集成以及高级场景处理,帮助开发者根据实际需求选择最优方案。
一、WebClient类:基础同步下载
WebClient是.NET Framework中最早的HTTP客户端类之一,适用于简单的同步文件下载场景。其核心方法为DownloadFile,可快速实现从URL到本地文件的保存。
using System.Net;
public void DownloadWithWebClient(string url, string savePath)
{
using (WebClient client = new WebClient())
{
try
{
client.DownloadFile(url, savePath);
Console.WriteLine("下载完成");
}
catch (WebException ex)
{
Console.WriteLine($"下载失败: {ex.Message}");
}
}
}
优点:代码简洁,适合小型文件或脚本场景。缺点:同步阻塞线程,无法取消或监控进度,.NET Core 3.1后已标记为过时。
二、HttpClient类:现代异步下载
HttpClient是.NET Core及后续版本推荐的HTTP客户端,支持异步操作、取消令牌和进度监控,是生产环境的主流选择。
1. 基础异步下载
using System.Net.Http;
using System.IO;
public async Task DownloadWithHttpClientAsync(string url, string savePath)
{
using (HttpClient client = new HttpClient())
{
try
{
byte[] fileBytes = await client.GetByteArrayAsync(url);
await File.WriteAllBytesAsync(savePath, fileBytes);
Console.WriteLine("下载完成");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"请求失败: {ex.Message}");
}
}
}
2. 流式下载(大文件优化)
对于大文件,应使用流式传输避免内存溢出:
public async Task DownloadLargeFileAsync(string url, string savePath)
{
using (HttpClient client = new HttpClient())
using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
using (var contentStream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
{
await contentStream.CopyToAsync(fileStream);
Console.WriteLine("大文件下载完成");
}
}
3. 进度监控实现
通过自定义Progress
public async Task DownloadWithProgressAsync(string url, string savePath)
{
using (HttpClient client = new HttpClient())
{
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
var totalBytes = response.Content.Headers.ContentLength ?? 0;
var buffer = new byte[8192];
int bytesRead;
long totalRead = 0;
using (var contentStream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(savePath, FileMode.Create))
{
while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalRead += bytesRead;
double progress = (double)totalRead / totalBytes * 100;
Console.WriteLine($"进度: {progress:F2}%");
}
}
}
}
三、FTP协议下载:专有协议实现
当需要从FTP服务器下载文件时,可使用FtpWebRequest类实现:
using System.Net;
public void DownloadFromFtp(string ftpUrl, string username, string password, string savePath)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(username, password);
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (FileStream fileStream = File.Create(savePath))
{
responseStream.CopyTo(fileStream);
Console.WriteLine($"FTP下载完成,状态: {response.StatusDescription}");
}
}
注意事项:需处理SSL/TLS加密连接时,需设置EnableSsl属性为true。
四、第三方库FluentFTP:高级FTP操作
对于复杂的FTP需求,推荐使用FluentFTP库,提供更简洁的API和断点续传功能。
1. 安装与基础下载
// 通过NuGet安装FluentFTP
// Install-Package FluentFTP
using FluentFTP;
public async Task DownloadWithFluentFtpAsync(string host, string username, string password,
string remotePath, string localPath)
{
using (var client = new FtpClient(host, username, password))
{
await client.ConnectAsync();
await client.DownloadFileAsync(localPath, remotePath, FtpLocalExists.Overwrite, true);
Console.WriteLine("FluentFTP下载完成");
}
}
2. 断点续传实现
public async Task ResumeDownloadWithFluentFtpAsync(string host, string username, string password,
string remotePath, string localPath)
{
using (var client = new FtpClient(host, username, password))
{
await client.ConnectAsync();
// 检查本地文件是否存在并获取已下载大小
long existingSize = File.Exists(localPath) ? new FileInfo(localPath).Length : 0;
await client.DownloadFileAsync(localPath, remotePath,
existingSize > 0 ? FtpLocalExists.Resume : FtpLocalExists.Overwrite,
true,
existingSize);
Console.WriteLine("断点续传完成");
}
}
五、高级场景处理
1. 多线程分段下载
通过Range头实现多线程并行下载:
public async Task MultiThreadDownloadAsync(string url, string savePath, int threadCount = 4)
{
using (HttpClient client = new HttpClient())
{
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));
long totalSize = long.Parse(response.Content.Headers.ContentLength.ToString());
long partSize = totalSize / threadCount;
var tasks = new List();
for (int i = 0; i
2. 下载限速控制
通过自定义HttpMessageHandler实现限速:
public class RateLimitedHandler : DelegatingHandler
{
private readonly int _bytesPerSecond;
private long _totalBytes;
private DateTime _lastCheckTime;
public RateLimitedHandler(int bytesPerSecond)
{
_bytesPerSecond = bytesPerSecond;
_lastCheckTime = DateTime.Now;
}
protected override async Task SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
var contentStream = await response.Content.ReadAsStreamAsync();
var memoryStream = new MemoryStream();
var buffer = new byte[8192];
int bytesRead;
while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await memoryStream.WriteAsync(buffer, 0, bytesRead);
_totalBytes += bytesRead;
var timeElapsed = (DateTime.Now - _lastCheckTime).TotalSeconds;
if (timeElapsed > 0 && _totalBytes / timeElapsed > _bytesPerSecond)
{
await Task.Delay(100); // 简单限速实现
}
}
response.Content = new StreamContent(memoryStream);
return response;
}
}
// 使用示例
public async Task LimitedDownloadAsync(string url, string savePath)
{
var handler = new RateLimitedHandler(1024 * 100); // 限制100KB/s
var client = new HttpClient(handler);
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
// 后续处理...
}
六、最佳实践总结
1. 资源管理:始终使用using语句确保流和客户端正确释放
2. 异常处理:区分网络异常、IO异常和业务异常
3. 异步编程:优先使用async/await避免线程阻塞
4. 大文件处理:采用流式传输而非全量缓冲
5. 安全性:验证URL合法性,防止路径遍历攻击
6. 进度反馈:通过IProgress
关键词:C#文件下载、HttpClient、WebClient、FTP下载、FluentFTP、异步编程、多线程下载、断点续传、限速控制
简介:本文详细介绍了C#中四种文件下载方法,包括基础WebClient类、现代HttpClient异步实现、FTP协议下载及FluentFTP第三方库应用,覆盖了同步/异步、大文件处理、进度监控、断点续传等高级场景,提供了完整的代码示例和最佳实践建议。