溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么使用C#?Winform實(shí)現(xiàn)復(fù)制文件顯示進(jìn)度

發(fā)布時(shí)間:2022-07-27 17:29:22 來(lái)源:億速云 閱讀:218 作者:iii 欄目:開(kāi)發(fā)技術(shù)

今天小編給大家分享一下怎么使用C# Winform實(shí)現(xiàn)復(fù)制文件顯示進(jìn)度的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

復(fù)制文件顯示進(jìn)度實(shí)際上就是文件流來(lái)復(fù)制文件,并在每一塊文件復(fù)制后,用進(jìn)度條來(lái)顯示復(fù)制情況。

一、本實(shí)例中主要是以線程和委托的方式,在使用Filestream類對(duì)文件進(jìn)行復(fù)制的同時(shí),使用ProgressBar來(lái)顯示文件復(fù)制進(jìn)度,下面對(duì)本實(shí)例中用到的關(guān)鍵技術(shù)進(jìn)行講解。

(1) 線程構(gòu)造函數(shù)

該構(gòu)造函數(shù)主要初始化Thread類的新實(shí)例。語(yǔ)法格式如下:

public Thread(ThreadStart start);

參數(shù)說(shuō)明:

start:ThreadStart委托,它表示線程開(kāi)始執(zhí)行時(shí)要調(diào)用的方法。

(2) 委托

在擁有此控件的基礎(chǔ)窗口句柄的線程上執(zhí)行指定的委托。語(yǔ)法格式如下:

public object Invoke(Delegate method);

參數(shù)說(shuō)明:

1method:包含要在控件的線程上下文中調(diào)用的方法的委托。
2返回值:正在被調(diào)用的委托的返回值,或者如果委托沒(méi)有返回值,則為空引用。

二、下面是程序的設(shè)計(jì)過(guò)程

(1)在VS中新建一個(gè)窗體應(yīng)用程序,并將其命名為FileCopyPlan。

(2)更改默認(rèn)窗體Form1的Name屬性為Frm_Main,在窗體中添加一個(gè)OpenFileDialog控件用來(lái)選擇源文件,添加一個(gè)FolderBrowserDialog控件,用來(lái)選擇文件保存路徑,添加兩個(gè)TextBox控件,分別用來(lái)顯示源文件和目的文件的路徑,添加3個(gè)Button控件,分別用來(lái)選擇源文件和目的文件的路徑,以及實(shí)現(xiàn)文件的路徑功能;添加一個(gè)ProgressBar控件用來(lái)顯示進(jìn)度條。

(3)程序的后臺(tái)代碼以及注釋如下:

public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }
        private System.Threading.Thread thdAddFile; //創(chuàng)建一個(gè)線程
        private string str = "";
        FileStream FormerOpen;//實(shí)例化FileStream類
        FileStream ToFileOpen;//實(shí)例化FileStream類

        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)//打開(kāi)文件對(duì)話框
                textBox1.Text = openFileDialog1.FileName;//獲取源文件的路徑
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)//打開(kāi)文件夾對(duì)話框
                textBox2.Text = folderBrowserDialog1.SelectedPath;//獲取目的文件的路徑
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (textBox1.Text.Length == 0 || textBox2.Text.Length == 0)
            {
                MessageBox.Show("請(qǐng)選擇原文件路徑或目的文件路徑。");
                return;
            }
            str = textBox1.Text;//記錄源文件的路徑
            str = "\\" + str.Substring(str.LastIndexOf('\\') + 1, str.Length - str.LastIndexOf('\\') - 1);//獲取源文件的名稱
            thdAddFile = new Thread(new ThreadStart(SetAddFile));//創(chuàng)建一個(gè)線程
            thdAddFile.Start();//執(zhí)行當(dāng)前線程
        }

        public delegate void AddFile();//定義委托
        /// <summary>
        /// 在線程上執(zhí)行委托
        /// </summary>
        public void SetAddFile()
        {
            this.Invoke(new AddFile(RunAddFile));//在線程上執(zhí)行指定的委托
        }

        /// <summary>
        /// 對(duì)文件進(jìn)行復(fù)制,并在復(fù)制完成后關(guān)閉線程
        /// </summary>
        public void RunAddFile()
        {
            CopyFile(textBox1.Text, textBox2.Text + str, 1024, progressBar1);//復(fù)制文件
            thdAddFile.Abort();//關(guān)閉線程
        }

        /// <summary>
        /// 文件的復(fù)制
        /// </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;//設(shè)置進(jìn)度欄的當(dāng)前位置為0
            progressBar1.Minimum = 0;//設(shè)置進(jìn)度欄的最小值為0
            FileStream fileToCreate = new FileStream(toFile, FileMode.Create);//創(chuàng)建目的文件,如果已存在將被覆蓋
            fileToCreate.Close();//關(guān)閉所有資源
            fileToCreate.Dispose();//釋放所有資源
            FormerOpen = new FileStream(FormerFile, FileMode.Open, FileAccess.Read);//以只讀方式打開(kāi)源文件
            ToFileOpen = new FileStream(toFile, FileMode.Append, FileAccess.Write);//以寫(xiě)方式打開(kāi)目的文件
            int max = Convert.ToInt32(Math.Ceiling((double)FormerOpen.Length / (double)SectSize));//根據(jù)一次傳輸?shù)拇笮?,?jì)算傳輸?shù)膫€(gè)數(shù)
            progressBar1.Maximum = max;//設(shè)置進(jìn)度欄的最大值
            int FileSize;//要拷貝的文件的大小
            if (SectSize < FormerOpen.Length)//如果分段拷貝,即每次拷貝內(nèi)容小于文件總長(zhǎng)度
            {
                byte[] buffer = new byte[SectSize];//根據(jù)傳輸?shù)拇笮?,定義一個(gè)字節(jié)數(shù)組
                int copied = 0;//記錄傳輸?shù)拇笮?
                int tem_n = 1;//設(shè)置進(jìn)度欄中進(jìn)度塊的增加個(gè)數(shù)
                while (copied <= ((int)FormerOpen.Length - SectSize))//拷貝主體部分
                {
                    FileSize = FormerOpen.Read(buffer, 0, SectSize);//從0開(kāi)始讀,每次最大讀SectSize
                    FormerOpen.Flush();//清空緩存
                    ToFileOpen.Write(buffer, 0, SectSize);//向目的文件寫(xiě)入字節(jié)
                    ToFileOpen.Flush();//清空緩存
                    ToFileOpen.Position = FormerOpen.Position;//使源文件和目的文件流的位置相同
                    copied += FileSize;//記錄已拷貝的大小
                    progressBar1.Value = progressBar1.Value + tem_n;//增加進(jìn)度欄的進(jìn)度塊
                }
                int left = (int)FormerOpen.Length - copied;//獲取剩余大小
                FileSize = FormerOpen.Read(buffer, 0, left);//讀取剩余的字節(jié)
                FormerOpen.Flush();//清空緩存
                ToFileOpen.Write(buffer, 0, left);//寫(xiě)入剩余的部分
                ToFileOpen.Flush();//清空緩存
            }
            else//如果整體拷貝,即每次拷貝內(nèi)容大于文件總長(zhǎng)度
            {
                byte[] buffer = new byte[FormerOpen.Length];//獲取文件的大小
                FormerOpen.Read(buffer, 0, (int)FormerOpen.Length);//讀取源文件的字節(jié)
                FormerOpen.Flush();//清空緩存
                ToFileOpen.Write(buffer, 0, (int)FormerOpen.Length);//寫(xiě)放字節(jié)
                ToFileOpen.Flush();//清空緩存
            }
            FormerOpen.Close();//釋放所有資源
            ToFileOpen.Close();//釋放所有資源
            if (MessageBox.Show("復(fù)制完成") == DialogResult.OK)//顯示"復(fù)制完成"提示對(duì)話框
            {
                progressBar1.Value = 0;//設(shè)置進(jìn)度欄的當(dāng)有位置為0
                textBox1.Clear();//清空文本
                textBox2.Clear();
                str = "";
            }
        }
    }

(4) 程序運(yùn)行結(jié)果如圖所示:

怎么使用C#?Winform實(shí)現(xiàn)復(fù)制文件顯示進(jìn)度

怎么使用C#?Winform實(shí)現(xiàn)復(fù)制文件顯示進(jìn)度

怎么使用C#?Winform實(shí)現(xiàn)復(fù)制文件顯示進(jìn)度

以上就是“怎么使用C# Winform實(shí)現(xiàn)復(fù)制文件顯示進(jìn)度”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI