C#设计:实现文件的多线程下载

一、程序设计要求

  1. 能够在下载过程中显示进度信息(如总大小、已下载大小、进度、下载速度、剩余大小、剩余时间、状态、下载的网址等)。
  2. 支持从指定的URL下载文件。
  3. 支持多线程并发下载文件。
  4. 提供友好的用户界面(UI)来下载。
  5. 具有良好的可扩展性,能够方便地添加新功能或修改现有功能。
  6. 代码结构清晰,易于理解和维护。

二、程序设计思路

2.1用户界面(UI)设计

  • 设计一个直观易用的图形用户界面,包含以下组件:
    • 序号:下载文件的序号
    • 文件名:下载的文件名称
    • 总大小:所下载文件的总大小
    • 已完成:显示已经完成的大小
    • 进度:显示下载进度。
    • 速度:显示下载速度。
    • 剩余:显示剩余的大小。
    • 时间:显示开始下载时间。
    • 状态:显示当前下载的状态(如“正在下载”、“已暂停”、“已完成”等)。
    • 网址:显示所下载的网站地址。

2.2下载流程设计

  • 当用户点击下载按钮时,开始执行以下流程:
    • 验证输入的URL是否有效。
    • 发送HTTP GET请求到指定的URL,获取文件的元数据信息(包括文件总大小)。
    • 根据获取到的文件总大小,初始化进度条和进度信息面板。
    • 创建一个下载任务,开始接收服务器的响应数据,并将数据写入到本地的文件中。
    • 在接收数据的过程中,实时更新进度条、已下载大小、下载速度、剩余大小等信息。
    • 估算剩余时间(可以使用已下载数据量和平均下载速度来计算)。
    • 当所有数据接收完毕后,标记下载状态为“已完成”,并关闭相关的下载资源。

2.3错误处理设计

  • 在下载过程中,可能会遇到各种错误,如网络连接中断、下载路径有误、URL无效等。
  • 当发生错误时,停止下载任务,并弹出错误信息。

三、窗体设计

根据设计思路设计窗体如下:

其中用到的主要控件及功能如下:

button:点击进行多线程下载任务。

listview:用于显示所下载文件的信息,将下载过程可视化。

四、代码实现

为了方便实现,将该程序分为4个大模块进行实现。

文件下载模块:主要实现连接下载地址和文件下载的处理

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;
using System.Net;

namespace Gac
{
    public class FileDownloader
    {
        /// <summary>
        /// 已下载文件长度
        /// </summary>
        private long downloadSize = 0;
        /// <summary>
        /// 原始文件长度
        /// </summary>
        private long fileSize = 0;
        /// <summary>
        /// 线程数
        /// </summary>
        private DownloadThread[] threads;
        /// <summary>
        /// 本地保存文件
        /// </summary>
        private string saveFile;
        /// <summary>
        /// 缓存各线程下载的长度
        /// </summary>
        public Dictionary<int, long> data = new Dictionary<int, long>();
        /// <summary>
        /// 每条线程下载的长度
        /// </summary>
        private long block;
        /// <summary>
        /// 下载路径
        /// </summary>
        private String downloadUrl;
        /// <summary>
        ///  获取线程数
        /// </summary>
        /// <returns> 获取线程数</returns>
        public int getThreadSize()
        {
            return threads.Length;
        }
        /// <summary>
        ///   获取文件大小
        /// </summary>
        /// <returns>获取文件大小</returns>
        public long getFileSize()
        {
            return fileSize;
        }
        /// <summary>
        /// 累计已下载大小
        /// </summary>
        /// <param name="size">累计已下载大小</param>
        public void append(long size)
        {
            lock (this)  //锁定同步..........
            {
                downloadSize += size;
            }

        }
        /// <summary>
        /// 更新指定线程最后下载的位置
        /// </summary>
        /// <param name="threadId">threadId 线程id</param>
        /// <param name="pos">最后下载的位置</param>
        public void update(int threadId, long pos)
        {
            if (data.ContainsKey(threadId))
            {
                this.data[threadId] = pos;
            }
            else
            {
                this.data.Add(threadId, pos);
            }
        }

        /// <summary>
        /// 构建下载准备,获取文件大小
        /// </summary>
        /// <param name="downloadUrl">下载路径</param>
        /// <param name="fileSaveDir"> 文件保存目录</param>
        /// <param name="threadNum">下载线程数</param>
        public FileDownloader(string downloadUrl, string fileSaveDir,string filename="", int threadNum=3)
        {
            try
            {
                if (string.IsNullOrEmpty(filename))
                {
                     filename = Uri.UnescapeDataString(Path.GetFileName(downloadUrl));//获取文件名称 uri 解码中文字符
                }
                //构建http 请求
                this.downloadUrl = downloadUrl;
                if (!Directory.Exists(fileSaveDir)) Directory.CreateDirectory(fileSaveDir);
                this.threads = new DownloadThread[threadNum];
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(downloadUrl);
                request.Referer = downloadUrl.ToString();
                request.Method = "GET";
                request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 2.0.1124)";
                request.ContentType = "application/octet-stream";
                request.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
                request.Timeout = 20 * 1000;
                request.AllowAutoRedirect = true;

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {

                        this.fileSize = response.ContentLength;//根据响应获取文件大小
                        if (this.fileSize <= 0) throw new Exception("获取文件大小失败");
                        
                        if (filename.Length == 0) throw new
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值