使用 C# 创建一个简单的文件下载器

在这篇文章中,我们将介绍如何使用 C# 和 Windows Forms 创建一个简单的文件下载器。这个程序将读取一个包含下载链接的文件,并显示每个文件的下载进度。

前置条件

在开始之前,确保你已经安装了以下开发工具:

  • Visual Studio
  • .NET Framework

步骤 1:创建 Windows Forms 应用程序

首先,我们需要创建一个新的 Windows Forms 应用程序。打开 Visual Studio,选择 "新建项目",然后选择 "Windows Forms 应用程序" 模板。

步骤 2:设计用户界面

在设计器中,我们需要添加以下控件:

  • 一个 Button 控件用于开始下载操作,命名为 btnTest
  • 一个 ListView 控件用于显示下载进度,命名为 listView1

配置 ListView 控件的列来显示下载项的信息,例如文件名、下载进度、速度等。

步骤 3:实现代码逻辑

接下来,我们需要编写代码来处理文件下载和进度更新。

以下是完整的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Gac;

namespace Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DownLoadFile dlf = new DownLoadFile();

        private void btnTest_Click(object sender, EventArgs e)
        {
            string[] lines = File.ReadAllLines("软件下载1.txt");
            for (int i = 0; i < lines.Length; i++)
            {
                string[] line = lines[i].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                if (line.Length == 2)
                {
                    string path = Uri.EscapeUriString(line[1]);
                    string filename = Path.GetFileName(path);
                    string dir = @"F:\test";
                    ListViewItem item = listView1.Items.Add(new ListViewItem(new string[] { (listView1.Items.Count + 1).ToString(), filename, "0", "0", "0%", "0", "0", DateTime.Now.ToString(), "等待中", line[1] }));
                    int id = item.Index;
                    dlf.AddDown(path, dir, id, id.ToString());
                }
            }
            dlf.StartDown();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dlf.ThreadNum = 3; // 线程数,不设置默认为3
            dlf.doSendMsg += SendMsgHander; // 下载过程处理事件
        }

        private void SendMsgHander(DownMsg msg)
        {
            switch (msg.Tag)
            {
                case DownStatus.Start:
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        listView1.Items[msg.Id].SubItems[8].Text = "开始下载";
                        listView1.Items[msg.Id].SubItems[7].Text = DateTime.Now.ToString();
                    });
                    break;
                case DownStatus.GetLength:
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        listView1.Items[msg.Id].SubItems[3].Text = msg.LengthInfo;
                        listView1.Items[msg.Id].SubItems[8].Text = "连接成功";
                    });
                    break;
                case DownStatus.End:
                case DownStatus.DownLoad:
                    this.Invoke(new MethodInvoker(() =>
                    {
                        this.Invoke((MethodInvoker)delegate ()
                        {
                            listView1.Items[msg.Id].SubItems[2].Text = msg.SizeInfo;
                            listView1.Items[msg.Id].SubItems[4].Text = msg.Progress.ToString() + "%";
                            listView1.Items[msg.Id].SubItems[5].Text = msg.SpeedInfo;
                            listView1.Items[msg.Id].SubItems[6].Text = msg.SurplusInfo;
                            if (msg.Tag == DownStatus.DownLoad)
                            {
                                listView1.Items[msg.Id].SubItems[8].Text = "下载中";
                            }
                            else
                            {
                                listView1.Items[msg.Id].SubItems[8].Text = "下载完成";
                            }
                            Application.DoEvents();
                        });
                    }));
                    break;
                case DownStatus.Error:
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        listView1.Items[msg.Id].SubItems[6].Text = "失败";
                        listView1.Items[msg.Id].SubItems[8].Text = msg.ErrMessage;
                        Application.DoEvents();
                    });
                    break;
            }
        }
    }
}

代码逐句分析

  1. 命名空间和类定义
    namespace Demo
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            // ...
        }
    }

    我们创建了一个命名空间 Demo 并定义了一个 Form1 类,这个类继承自 Form 类。

  2. 定义下载对象
    DownLoadFile dlf = new DownLoadFile();

    Form1 类中创建一个 DownLoadFile 对象 dlf,它将用于处理文件下载操作。

  3. 按钮点击事件
    private void btnTest_Click(object sender, EventArgs e)
    {
        // ...
    }

    这是按钮 (btnTest) 的点击事件处理方法,它将触发下载操作。

  4. 读取下载链接并启动下载
    string[] lines = File.ReadAllLines("软件下载1.txt");
    for (int i = 0; i < lines.Length; i++)
    {
        string[] line = lines[i].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
        if (line.Length == 2)
        {
            string path = Uri.EscapeUriString(line[1]);
            string filename = Path.GetFileName(path);
            string dir = @"F:\test";
            ListViewItem item = listView1.Items.Add(new ListViewItem(new string[] { (listView1.Items.Count + 1).ToString(), filename, "0", "0", "0%", "0", "0", DateTime.Now.ToString(), "等待中", line[1] }));
            int id = item.Index;
            dlf.AddDown(path, dir, id, id.ToString());
        }
    }
    dlf.StartDown();

    从文件 "软件下载1.txt" 中读取所有行。对每一行进行处理,解析出文件路径。在 ListView 中添加一项以显示下载信息。调用 dlf.AddDown 方法添加下载任务,并启动下载。

  5. 窗体加载事件
    private void Form1_Load(object sender, EventArgs e)
    {
        dlf.ThreadNum = 3; // 线程数,不设置默认为3
        dlf.doSendMsg += SendMsgHander; // 下载过程处理事件
    }

    在窗体加载时设置下载线程数(默认为3)。

    将 SendMsgHander 方法附加到 doSendMsg 事件,用于处理下载过程中的消息。
  6. 下载消息处理
    private void SendMsgHander(DownMsg msg)
    {
        switch (msg.Tag)
        {
            case DownStatus.Start:
                this.Invoke((MethodInvoker)delegate ()
                {
                    listView1.Items[msg.Id].SubItems[8].Text = "开始下载";
                    listView1.Items[msg.Id].SubItems[7].Text = DateTime.Now.ToString();
                });
                break;
            case DownStatus.GetLength:
                this.Invoke((MethodInvoker)delegate ()
                {
                    listView1.Items[msg.Id].SubItems[3].Text = msg.LengthInfo;
                    listView1.Items[msg.Id].SubItems[8].Text = "连接成功";
                });
                break;
            case DownStatus.End:
            case DownStatus.DownLoad:
                this.Invoke(new MethodInvoker(() =>
                {
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        listView1.Items[msg.Id].SubItems[2].Text = msg.SizeInfo;
                        listView1.Items[msg.Id].SubItems[4].Text = msg.Progress.ToString() + "%";
                        listView1.Items[msg.Id].SubItems[5].Text = msg.SpeedInfo;
                        listView1.Items[msg.Id].SubItems[6].Text = msg.SurplusInfo;
                        if (msg.Tag == DownStatus.DownLoad)
                        {
                            listView1.Items[msg.Id].SubItems[8].Text = "下载中";
                        }
                        else
                        {
                            listView1.Items[msg.Id].SubItems[8].Text = "下载完成";
                        }
                        Application.DoEvents();
                    });
                }));
                break;
            case DownStatus.Error:
                this.Invoke((MethodInvoker)delegate ()
                {
                    listView1.Items[msg.Id].SubItems[6].Text = "失败";
                    listView1.Items[msg.Id].SubItems[8].Text = msg.ErrMessage;
                    Application.DoEvents();
                });
                break;
        }
    }

    根据 DownMsg 的 Tag 属性处理不同的下载状态。使用 Invoke 方法确保跨线程调用更新 UI 控件。

    总结

    通过上述步骤,我们创建了一个简单的文件下载器。这个应用程序可以读取下载链接文件,并显示每个文件的下载进度和状态。

  • 29
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值