通过 HttpClient 下载网络文件
前言:之前有需求从某个网站自动下载其文件。而事先我是没有这方面的开发经验的。找了许多资料大多是采用 WebClient 类进行网络文件的获取。然而我去 MSDN 查找相关文档时发现目前官方是不建议采用 WebClient 来开发新的项目的。而目前有关 HttpClient 的操作实例比较少故做此篇供大家参考。
其实 WebClient 和 HttpClient 类的相关代码有些类似,但前者为同步后者为异步,实际代码中有许多需要注意的事项。
一、首先,遵照 HttpClient 的设计理念,只定义一个 HttpClient 实例对象并重复使用。
//这里引用的是 MSDN 文档内的范例public class GoodController : ApiController{private static readonly HttpClient HttpClient;static GoodController(){HttpClient = new HttpClient();}}
二、实现 DownloadFile 方法下载并存储文件
/// <summary>/// 从网页上下载文件并保存到指定目录/// </summary>/// <param name=\"url\">文件下载地址</param>/// <param name=\"directoryName\">文件下载目录</param>/// <param name=\"fileName\">不包括扩展名</param>/// <returns>下载是否成功</returns>public async Task<bool> DownloadFile(string url, string directoryName,string fileName){bool sign = true;try{HttpResponseMessage response = await HttpClient.GetAsync(url);using (Stream stream = await response.Content.ReadAsStreamAsync()){//获取文件后缀string extension = Path.GetExtension(response.RequestMessage.RequestUri.ToString());using (FileStream fileStream = new FileStream($\"{directoryName}/{fileName}{extension}\", FileMode.CreateNew)){byte[] buffer = new byte[BufferSize];int readLength = 0;int length;while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0){readLength += length;// 写入到文件fileStream.Write(buffer, 0, length);}}}}catch (IOException){//这里的异常捕获并不完善,请结合实际操作而定sign = false;Console.WriteLine(\"Downloader.DownloadFile:请检查文件名是否重复!\");}return sign;}
三、上面是文件下载,由于下载文件普遍要分析 html 文件(写的可能相当糟糕,List 集合用的感觉十分不恰当,似乎有更好的解决方案)……
public async Task<string> LoadHtml(string url, Encoding encoding){HttpResponseMessage response = await HttpClient.GetAsync(url);List<byte> bytes = new List<byte>();using (Stream stream = await response.Content.ReadAsStreamAsync()){byte[] buffer = new byte[BufferSize];int length;while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0){for (int i = 0; i < length; i++){bytes.Add(buffer[i]);}}}return encoding.GetString(bytes.ToArray());}
方法的结果可通过 task.Result(); 的方式获取
总结:我对 HttpClient 的理解并不够深入,如有不足,恳请赐教!