管理

网络文件下载器 - C#小函数类推荐

Posted on 2024-12-13 00:39  lzhdim  阅读(1819)  评论(0编辑  收藏  举报

       此文记录的是下载网络文件的操作类。

/***

    网络文件下载器

    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 私有函数 } }

 

Copyright © 2000-2022 Lzhdim Technology Software All Rights Reserved