表妹上高三了,需要在某网站上下载试卷刷题,通常每周日回家需要下载某些名校的N套题,然后筛选部分后打印再带回寝室。她把下载的这个任务交给了小编,小编也不想动手点击,幸好小编学过几天编程,于是想用程序的方式解决这个问题,首先要解决的是通过列表获取下载地址,这步骤已经解决了,就是通过HttpClient读取页面的内容通过正则表达式匹配列表的下载链接然后自动下载,但是遇到问题,HttpClient貌似不能直接在程序中下载文件。于是就查到用文件流的方式来读取,具体怎么实现,本文将分享出来。.
准备工作
这里我们拿微软官方下载文件.NET7来做例子,首先找到网址:
https://dotnet.microsoft.com/zh-cn/download
然后找到下载地址,点击下载后在浏览器的下载内容中复制下载地址:
https://download.visualstudio.microsoft.com/download/pr/5b9d1f0d-9c56-4bef-b950-c1b439489b27/b4aa387715207faa618a99e9b2dd4e35/dotnet-sdk-7.0.100-win-x64.exe
在实际的开发环境中,可以请求后用正则表达式批量抓取。
编写代码
const int BufferSize = 8192;// 定义缓存大小,8192 字节static readonly HttpClient _httpClient = new HttpClient();//用单例创建http请求/// <summary>/// 从网页上下载文件并保存到指定目录/// </summary>/// <param name="url">文件下载地址</param>/// <param name="directoryName">文件下载目录</param>/// <param name="fileName">不包括扩展名</param>/// <returns>下载是否成功</returns>static 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("请检查文件名是否重复或者超时!");}return sign;}
调用:
我们用main方法来模拟调用
static void Main(string[] args){ //获取的url地址string down = "https://download.visualstudio.microsoft.com/download/pr/5b9d1f0d-9c56-4bef-b950-c1b439489b27/b4aa387715207faa618a99e9b2dd4e35/dotnet-sdk-7.0.100-win-x64.exe";string path = AppDomain.CurrentDomain.BaseDirectory + "//Files";if (!Directory.Exists(path)){ Directory.CreateDirectory(path); }string filename = System.IO.Path.GetFileName(down);//由于main方法不是异步方法,故调用需要.GetAwaiter().GetResult(),正常不建议这么做var rel= DownloadFile(down, path, filename).GetAwaiter().GetResult();Console.WriteLine(rel);}//返回true
可以在bin目录查看下载成功了

结语
本案例实现了用程序下载文件的例子,使用了HttpClient请求,获取内容后通过文件流来保存文件。本案例仅供参考,程序猿的你有啥更好的方法吗?文笔水平有限,欢迎留言或提出异议。