C# Winform实现复制文件显示进度

 更新时间:2022年07月27日 16:59:56   作者:JR.Zhang  
这篇文章主要介绍了C# Winform实现复制文件显示进度,用进度条来显示复制情况,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

复制文件显示进度实际上就是文件流来复制文件,并在每一块文件复制后,用进度条来显示复制情况。

一、本实例中主要是以线程和委托的方式,在使用Filestream类对文件进行复制的同时,使用ProgressBar来显示文件复制进度,下面对本实例中用到的关键技术进行讲解。

(1) 线程构造函数

该构造函数主要初始化Thread类的新实例。语法格式如下:

public Thread(ThreadStart start);

参数说明:

start:ThreadStart委托,它表示线程开始执行时要调用的方法。

(2) 委托

在拥有此控件的基础窗口句柄的线程上执行指定的委托。语法格式如下:

public object Invoke(Delegate method);

参数说明:

1method:包含要在控件的线程上下文中调用的方法的委托。
2返回值:正在被调用的委托的返回值,或者如果委托没有返回值,则为空引用。

二、下面是程序的设计过程

(1)在VS中新建一个窗体应用程序,并将其命名为FileCopyPlan。

(2)更改默认窗体Form1的Name属性为Frm_Main,在窗体中添加一个OpenFileDialog控件用来选择源文件,添加一个FolderBrowserDialog控件,用来选择文件保存路径,添加两个TextBox控件,分别用来显示源文件和目的文件的路径,添加3个Button控件,分别用来选择源文件和目的文件的路径,以及实现文件的路径功能;添加一个ProgressBar控件用来显示进度条。

(3)程序的后台代码以及注释如下:

public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }
        private System.Threading.Thread thdAddFile; //创建一个线程
        private string str = "";
        FileStream FormerOpen;//实例化FileStream类
        FileStream ToFileOpen;//实例化FileStream类

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)//打开文件对话框
                textBox1.Text = openFileDialog1.FileName;//获取源文件的路径
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)//打开文件夹对话框
                textBox2.Text = folderBrowserDialog1.SelectedPath;//获取目的文件的路径
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Length == 0 || textBox2.Text.Length == 0)
            {
                MessageBox.Show("请选择原文件路径或目的文件路径。");
                return;
            }
            str = textBox1.Text;//记录源文件的路径
            str = "\\" + str.Substring(str.LastIndexOf('\\') + 1, str.Length - str.LastIndexOf('\\') - 1);//获取源文件的名称
            thdAddFile = new Thread(new ThreadStart(SetAddFile));//创建一个线程
            thdAddFile.Start();//执行当前线程
        }

        public delegate void AddFile();//定义委托
        /// <summary>
        /// 在线程上执行委托
        /// </summary>
        public void SetAddFile()
        {
            this.Invoke(new AddFile(RunAddFile));//在线程上执行指定的委托
        }

        /// <summary>
        /// 对文件进行复制,并在复制完成后关闭线程
        /// </summary>
        public void RunAddFile()
        {
            CopyFile(textBox1.Text, textBox2.Text + str, 1024, progressBar1);//复制文件
            thdAddFile.Abort();//关闭线程
        }

        /// <summary>
        /// 文件的复制
        /// </summary>
        /// <param FormerFile="string">源文件路径</param>
        /// <param toFile="string">目的文件路径</param> 
        /// <param SectSize="int">传输大小</param> 
        /// <param progressBar="ProgressBar">ProgressBar控件</param> 
        public void CopyFile(string FormerFile, string toFile, int SectSize, ProgressBar progressBar1)
        {
            progressBar1.Value = 0;//设置进度栏的当前位置为0
            progressBar1.Minimum = 0;//设置进度栏的最小值为0
            FileStream fileToCreate = new FileStream(toFile, FileMode.Create);//创建目的文件,如果已存在将被覆盖
            fileToCreate.Close();//关闭所有资源
            fileToCreate.Dispose();//释放所有资源
            FormerOpen = new FileStream(FormerFile, FileMode.Open, FileAccess.Read);//以只读方式打开源文件
            ToFileOpen = new FileStream(toFile, FileMode.Append, FileAccess.Write);//以写方式打开目的文件
            int max = Convert.ToInt32(Math.Ceiling((double)FormerOpen.Length / (double)SectSize));//根据一次传输的大小,计算传输的个数
            progressBar1.Maximum = max;//设置进度栏的最大值
            int FileSize;//要拷贝的文件的大小
            if (SectSize < FormerOpen.Length)//如果分段拷贝,即每次拷贝内容小于文件总长度
            {
                byte[] buffer = new byte[SectSize];//根据传输的大小,定义一个字节数组
                int copied = 0;//记录传输的大小
                int tem_n = 1;//设置进度栏中进度块的增加个数
                while (copied <= ((int)FormerOpen.Length - SectSize))//拷贝主体部分
                {
                    FileSize = FormerOpen.Read(buffer, 0, SectSize);//从0开始读,每次最大读SectSize
                    FormerOpen.Flush();//清空缓存
                    ToFileOpen.Write(buffer, 0, SectSize);//向目的文件写入字节
                    ToFileOpen.Flush();//清空缓存
                    ToFileOpen.Position = FormerOpen.Position;//使源文件和目的文件流的位置相同
                    copied += FileSize;//记录已拷贝的大小
                    progressBar1.Value = progressBar1.Value + tem_n;//增加进度栏的进度块
                }
                int left = (int)FormerOpen.Length - copied;//获取剩余大小
                FileSize = FormerOpen.Read(buffer, 0, left);//读取剩余的字节
                FormerOpen.Flush();//清空缓存
                ToFileOpen.Write(buffer, 0, left);//写入剩余的部分
                ToFileOpen.Flush();//清空缓存
            }
            else//如果整体拷贝,即每次拷贝内容大于文件总长度
            {
                byte[] buffer = new byte[FormerOpen.Length];//获取文件的大小
                FormerOpen.Read(buffer, 0, (int)FormerOpen.Length);//读取源文件的字节
                FormerOpen.Flush();//清空缓存
                ToFileOpen.Write(buffer, 0, (int)FormerOpen.Length);//写放字节
                ToFileOpen.Flush();//清空缓存
            }
            FormerOpen.Close();//释放所有资源
            ToFileOpen.Close();//释放所有资源
            if (MessageBox.Show("复制完成") == DialogResult.OK)//显示"复制完成"提示对话框
            {
                progressBar1.Value = 0;//设置进度栏的当有位置为0
                textBox1.Clear();//清空文本
                textBox2.Clear();
                str = "";
            }
        }
    }

(4) 程序运行结果如图所示:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Unity3D开发实战之五子棋游戏

    Unity3D开发实战之五子棋游戏

    这篇文章主要为大家详细介绍了Unity3D开发实战之五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • 解析C#中的分部类和分部方法

    解析C#中的分部类和分部方法

    这篇文章主要介绍了C#中的分部类和分部方法,讲解了类的拆分和方法的定义的拆分,需要的朋友可以参考下
    2016-01-01
  • C#职责链模式实例详解

    C#职责链模式实例详解

    这篇文章主要介绍了C#职责链模式,以实例形式完整分析了C#职责链模式的相关技巧与实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • C#根据权重抽取随机数

    C#根据权重抽取随机数

    最近在开发过程中遇到一个需要做带权随机的处理,本文主要介绍了C#根据权重抽取随机数,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • C#调用python脚本的方法详解

    C#调用python脚本的方法详解

    这篇文章主要为大家详细介绍了C#调用python脚本的方法,文中通过示例代码介绍的非常详细,感兴趣的朋友们下面随着小编来一起学习学习吧
    2023-11-11
  • C#实现判断字符串中是否包含中文的方法

    C#实现判断字符串中是否包含中文的方法

    这篇文章主要介绍了C#实现判断字符串中是否包含中文的方法,非常实用的功能,需要的朋友可以参考下
    2014-08-08
  • unity自带寻路(导航)系统 Nav Mesh导航网格

    unity自带寻路(导航)系统 Nav Mesh导航网格

    这篇文章主要为大家详细介绍了unity自带寻路(导航)系统,Nav Mesh导航网格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C#预定义的基础类型转换

    C#预定义的基础类型转换

    这篇文章介绍了C#预定义的基础类型转换,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C#中的委托、事件学习笔记

    C#中的委托、事件学习笔记

    这篇文章主要介绍了C#中的委托、事件学习笔记,本文讲解了委托delegate、事件的相关知识并给出代码实例,需要的朋友可以参考下
    2015-01-01
  • C#实现鼠标左右键切换效果

    C#实现鼠标左右键切换效果

    这篇文章主要为大家详细介绍了如何利用C#实现鼠标左右键切换功能,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2022-12-12

最新评论