C# winform带进度条的图片下载

时间:2022-09-11 13:15:14

代码如下:

    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            btnDownload.FlatStyle = FlatStyle.Flat;
            btnDownload.FlatAppearance.BorderSize = 0;
            btnDownload.FlatAppearance.MouseOverBackColor = Color.LightSkyBlue;
            btnDownload.FlatAppearance.MouseDownBackColor = Color.SkyBlue;
            txtWebSiteUrl.Focus();
            cmbRegexs.Items.AddRange(new string[] 
            {
                "--请选择正确的正则表达式--",
                "<img\\s+src=\"(.+)\"\\s+/>", 
                "<img\\s+src=\"(.+)\"\\s+border=\".+\"\\s+hspace=\".+\"\\s+smallsrc=\".+\"\\s+/>",
                "<img\\s+src=\"(.+)\"\\s+alt=\"(.+)?\"\\s+style=\"(.+)?\"/>"
            });
            cmbRegexs.SelectedIndex = 0;
            btnDownload.Click += new EventHandler(btnDownload_Click);
        }

        void btnDownload_Click(object sender, EventArgs e)
        {
            try
            {
                string url = txtWebSiteUrl.Text.Trim();//网址
                string regex = cmbRegexs.SelectedItem.ToString();//正则表达式

                #region 基本信息验证

                if (string.IsNullOrEmpty(url) || !Regex.IsMatch(url, "[a-zA-z]+://[^\\s]*", RegexOptions.ECMAScript)) { txtWebSiteUrl.Text = ""; txtWebSiteUrl.Focus(); /*提示太烦了,所以就定位*/ return; }
                if (regex == "--请选择正确的正则表达式--") { MessageBox.Show("请选择正则表达式"); return; }

                #endregion

                string lofter_code = GetWebCode(url, Encoding.UTF8);//获取网页内容
                MatchCollection matchcollection = Regex.Matches(lofter_code, regex);//查询匹配项
                if (matchcollection.Count <= 0)
                    throw new Exception("该网页没有图片");

                string Directory = string.Empty;//保存的文件夹

                #region 获取文件夹路径

                FolderBrowserDialog folder = new FolderBrowserDialog();//文件夹选择
                folder.RootFolder = Environment.SpecialFolder.DesktopDirectory;//默认位置为桌面
                folder.ShowNewFolderButton = true;//可以新建文件夹
                if (folder.ShowDialog() == DialogResult.OK)
                {
                    Directory = folder.SelectedPath;
                    btnDownload.Enabled = false; txtWebSiteUrl.Enabled = false; cmbRegexs.Enabled = false;/*禁用按钮和文本和下拉框*/ 
                }
                else return;

                #endregion

                int i = 0;
                WebClient wc = new WebClient();
                wc.Encoding = Encoding.UTF8;
                foreach (Match item in matchcollection)
                {
                    i++;
                    DownloadFile(item.Groups[1].Value, Path.Combine(Directory, GetPictureName(item.Groups[1].Value)), pbProgressBar);//不是很卡
                    //wc.DownloadFileAsync(item.Groups[1].Value, Path.Combine(Directory, GetPictureName(item.Groups[1].Value)));//速度快,但无法设置进度条,并且很卡
                    lblResult.Text = "还有【" + (matchcollection.Count - i) + "】张图片未下载";
                }
                lblResult.Text = "下载完成,共下载【" + matchcollection.Count + "】张图片";
                btnDownload.Enabled = true; txtWebSiteUrl.Enabled = true; cmbRegexs.Enabled = true;/*启用按钮和文本和下拉框*/ 
            }
            catch (Exception ex)
            {
                btnDownload.Enabled = true; txtWebSiteUrl.Enabled = true; cmbRegexs.Enabled = true;/*启用按钮和文本和下拉框*/ 
                lblResult.Text = "错误:" + ex.Message;
            }

        }

        /// <summary>        
        /// 下载文件
        /// </summary>        
        /// <param name="url">下载文件地址</param>       
        /// <param name="filename">下载后的存放地址</param>        
        /// <param name="prog">用于显示的进度条</param>        
        public static void DownloadFile(string url, string filename, System.Windows.Forms.ProgressBar prog)
        {
            try
            {
                System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
                System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
                long totalBytes = myrp.ContentLength;
                if (prog != null)
                {
                    prog.Maximum = (int)totalBytes;
                }
                System.IO.Stream st = myrp.GetResponseStream();
                System.IO.Stream so = new System.IO.FileStream(filename, System.IO.FileMode.Create);
                long totalDownloadedByte = 0;
                byte[] by = new byte[1024];
                int osize = st.Read(by, 0, (int)by.Length);
                while (osize > 0)
                {
                    totalDownloadedByte = osize + totalDownloadedByte;
                    System.Windows.Forms.Application.DoEvents();
                    so.Write(by, 0, osize);
                    if (prog != null)
                    {
                        prog.Value = (int)totalDownloadedByte;
                    }
                    osize = st.Read(by, 0, (int)by.Length);
                }
                so.Close();
                st.Close();
            }
            catch (System.Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        /// <summary>
        /// 获取指定网页的内容
        /// </summary>
        /// <param name="path">网页地址</param>
        /// <param name="encoding">字符编码格式</param>
        /// <returns></returns>
        public static string GetWebCode(string path, Encoding encoding)
        {
            System.Net.WebRequest wr = System.Net.WebRequest.Create(path);
            System.IO.Stream s = wr.GetResponse().GetResponseStream();
            if (s == null) return null;
            System.IO.StreamReader sr = new System.IO.StreamReader(s, encoding);
            string all = sr.ReadToEnd();//读取网站的数据
            sr.Close();
            s.Close();
            return all;
        }

        /// <summary>
        /// 获取图片名
        /// </summary>
        /// <param name="url">图片地址</param>
        /// <returns></returns>
        public static string GetPictureName(string url)
        {
            return url.Remove(0, url.LastIndexOf('/') + 1);
        }