首页 > 编程语言 >使用 C# 创建一个简单的文件下载器

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

时间:2024-06-22 12:57:26浏览次数:15  
标签:listView1 SubItems C# 创建 Items msg Id 下载 Text

在这篇文章中,我们将介绍如何使用 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 控件。

    总结

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

标签:listView1,SubItems,C#,创建,Items,msg,Id,下载,Text
From: https://blog.csdn.net/Whiskey_T/article/details/139868909

相关文章

  • Python连接Etcd集群基础教程
    1、背景介绍最近接手了一个项目,项目是使用Python开发的,其中使用到了Etcd,但是项目之前开发的方式,只能够支持单节点连接Etcd,不能够在Etcd节点发生故障时,自动转移。因此需要实现基于现有etcdsdk开发一个能够实现故障转移的功能,或者更换etcdsdk来实现故障转移等功能。先来看看项......
  • [暴力 Trick] 根号分治
    根号分治PS:本篇博客题目分析及内容(除代码)均来自于paulzrm根号分治,是暴力美学的集大成体现。与其说是一种算法,我们不如称它为一个常用的trick。首先,我们引入一道入门题目CF1207FRemainderProblem:给你一个长度为$5\times10^5$的序列,初值为$0$,你要完成$q$次操作,操作有如......
  • 【C#进阶】LINQ和数据库操作_2024-06-22
    当我们踏入现代软件开发的世界,高效地管理和操作数据成为了编程的核心技能之一。让我们一步步来,用最直白的语言讲解这些与数据库操作和LINQ相关的知识点。LINQand数据库操作LINQ(LanguageIntegratedQuery,语言集成查询)是C#中一种强大而灵活的查询技术,它允许你以统一的方式查询......
  • 分享:Javascript开源桌面环境-Puter
    Puter这是一个运行在浏览器里的桌面操作系统,提供了笔记本、代码编辑器、终端、画图、相机、录音等应用和一些小游戏。该项目作者出于性能方面的考虑没有选择Vue和React技术栈,而是采用的JavaScript和jQuery构建,支持Docker一键部署和在线使用。 简介:Puter是一......
  • 通讯协议大全(UART,RS485,SPI,IIC)
    参考自: 常见的通讯协议总结(USART、IIC、SPI、485、CAN)-CSDN博客UART那么好用,为什么单片机还需要I2C和SPI?_哔哩哔哩_bilibili5分钟看懂!串口RS232RS485最本质的区别!_哔哩哔哩_bilibili喜欢几位博主老师老师的还请看原贴/原视频数据通信 数据通信是指通过某种传......
  • RAG与LLM原理及实践(2)--- RAG结合LLM function调用的原理及落地实践
    花一点时间继续写下,RAG结合LLM。通过上一篇文章你应该知道为什么RAG要结合LLM,或者说为什么LLM要结合RAG使得LLM更强大,特别是当LLM应用在人机对话等方面的时候。只要涉及一问一答,并通过上下文继续丰富对话,就会涉及到他。这个是看事情的两个维度。就像是买钟送电池还是买电池送......
  • RAG与LLM原理及实践(3)--- RAG结合LLM的local实现并附完整代码
    在写RAG结合LLM时,如果你读了我前面写的文章,你应该对里面的技术原理及流程有了很详细的了解。在上一篇文章讲了如何在通义千问中使用function的方式来完成LLM与RAG的结合。其实LLM结合RAG的方式可以有很多种,但是原理都是上一节介绍的,其实本质上就是要LLM知道,哪一类问题‘我’......
  • C/C++ 堆栈stack算法详解及源码
    堆栈(stack)是一种常见的数据结构,具有"先进后出"(LastInFirstOut,LIFO)的特性。堆栈算法允许在堆栈顶部进行元素的插入和删除操作。堆栈的操作包括:入栈(Push):将元素添加到堆栈的顶部。出栈(Pop):从堆栈的顶部移除元素。取栈顶元素(Top):获取堆栈顶部的元素,但不对其进行删除操作。......
  • C/C++ stack实现深度优先搜索DFS算法详解及源码
    深度优先搜索(DepthFirstSearch,DFS)是一种图遍历算法,它从一个节点开始,通过访问其相邻节点的方式,依次深入到图中的更深层次。Stack(栈)是一种先进后出(LastInFirstOut,LIFO)的数据结构,它非常适合实现DFS算法。首先,我们来解释一下Stack实现DFS算法的原理。DFS算法的核心思想是......
  • Scrum Master JobGPT
    ScrumMasterJobGPT:您在当前就业市场中茁壮成长的新工具。在搜索或选择新的ScrumMaster工作时获得帮助。     鉴于ScrumMaster和敏捷教练目前所处的动荡时期,我们的社区必须团结一致。这就是ScrumMasterJobGPT,您在就业市场上的新盟友。这个免费工具可以通过付费的......