此文记录的是下载网络文件的操作类。
/*** 网络文件下载器 Austin Liu 刘恒辉 Project Manager and Software Designer E-Mail: lzhdim@163.com Blog: http://lzhdim.cnblogs.com Date: 2024-01-15 15:18:00 使用方法: DownloadWebFileUtil.DownloadFile("https://lzhdim.cnblogs.com/default.html","d:\default.html"): ***/ namespace Lzhdim.LPF.Utility { using System; using System.IO; using System.Net; using System.Text; using System.Net.Security; using System.Security.Cryptography.X509Certificates; /// <summary> /// 下载网页操作类 /// </summary> public static class DownloadWebFileUtil { /// <summary> /// 同步下载方法,支持断点续传,计算下载速度,下载进度 /// </summary> /// <param name="url">下载链接</param> /// <param name="savePath">文件保存路径,C://xxx.zip</param> /// <param name="progressCallBack">进度回调</param> /// <param name="downloadMsgCallBack">速度回调</param> /// <returns>true:下载成功,false:下载失败</returns> public static bool DownloadFile(string url, string savePath, Action<double> progressCallBack = null, Action<string> downloadMsgCallBack = null) { ServicePointManager.DefaultConnectionLimit = 50; string responseContent = ""; HttpWebRequest httpWebRequest = null; try { if (string.IsNullOrEmpty(savePath)) return false; long rangeBegin = 0;//记录已经下载了多少 if (File.Exists(savePath)) rangeBegin = new FileInfo(savePath).Length; if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; httpWebRequest = WebRequest.Create(url) as HttpWebRequest; } else httpWebRequest = (HttpWebRequest)WebRequest.Create(url); //httpWebRequest.Timeout = 300000; //httpWebRequest.ReadWriteTimeout = 60 * 1000; httpWebRequest.Method = "GET"; httpWebRequest.KeepAlive = false; httpWebRequest.ServicePoint.Expect100Continue = false; httpWebRequest.Proxy = null; if (rangeBegin > 0) httpWebRequest.AddRange(rangeBegin); using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse()) { using (Stream responseStream = httpWebResponse.GetResponseStream()) { if (responseStream == null) return false; long totalLength = httpWebResponse.ContentLength; if (totalLength == rangeBegin) { progressCallBack?.Invoke(100); return true; } if (totalLength == 0 || rangeBegin > totalLength) { progressCallBack?.Invoke(0); return false; } long offset = rangeBegin; long oneSecondDonwload = 0; var beginSecond = DateTime.Now.Second; //savePath = Path.Combine(savePath,
httpWebResponse.ResponseUri.LocalPath.Substring(
httpWebResponse.ResponseUri.LocalPath.LastIndexOf('/') + 1)); //自动获取文件名 using (Stream stream = new FileStream(savePath, FileMode.Append, FileAccess.Write)) { byte[] bArr = new byte[1024 * 8 * 1024]; int size = 0; while ((size = responseStream.Read(bArr, 0, (int)bArr.Length)) > 0) { try { stream.Write(bArr, 0, size); oneSecondDonwload += size; offset = offset + size; var endSencond = DateTime.Now.Second; if (beginSecond != endSencond) { string outSize = GetFileSizeTypeBySize(oneSecondDonwload / (endSencond - beginSecond)); downloadMsgCallBack?.Invoke($"{outSize}/S"); beginSecond = DateTime.Now.Second; oneSecondDonwload = 0; } progressCallBack?.Invoke(Math.Round((offset / (totalLength * 1.0)) * 100, 2)); } catch { return false; } } responseContent = savePath; } } httpWebResponse?.Close(); } } catch { responseContent = ""; return false; } finally { httpWebRequest?.Abort(); } return true; } /// <summary> /// 根据URL获取XML文档文本内容 /// </summary> /// <param name="URL">XML文件网址</param> /// <returns>XML文本内容</returns> internal static string GetWebXMLFile(string URL) { try { start: HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(URL); req.Method = "GET"; req.Timeout = 60000; req.KeepAlive = true; req.AllowAutoRedirect = true; HttpWebResponse rps = (HttpWebResponse)req.GetResponse(); if (rps.StatusCode != HttpStatusCode.OK) { goto start; } Stream respStream = rps.GetResponseStream(); using (StreamReader reader = new StreamReader(respStream, Encoding.GetEncoding("utf-8"))) { //ReadToEnd方法不好使,有时候抛异常:无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接 //string text = reader.ReadToEnd(); string text = string.Empty; string line = string.Empty; while ((line = reader.ReadLine()) != null) { text += line; } reader.Close(); return text; } } catch { return string.Empty; } } #region 私有函数 /// <summary> /// 临时返回函数 /// </summary> /// <param name="sender"></param> /// <param name="certificate"></param> /// <param name="chain"></param> /// <param name="sslPolicyErrors"></param> /// <returns></returns> private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } /// <summary> /// 获取文件大小 /// </summary> /// <param name="fileSize">文件大小</param> /// <returns>格式化后的文本</returns> private static string GetFileSizeTypeBySize(long fileSize) { if (fileSize < 1024) return $"{fileSize}B"; if (fileSize / 1024 < 1024) return $"{fileSize / 1024}KB"; if (fileSize / (1024 * 1024) < 1024) return $"{fileSize / (1024 * 1024)}MB"; else return $"{fileSize / (1024 * 1024 * 1024)}GB"; } #endregion 私有函数 } }
Austin Liu 刘恒辉
Project Manager and Software Designer E-Mail:lzhdim@163.com Blog:https://lzhdim.cnblogs.com 欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。 |