網站首頁 編程語言 正文
復制文件顯示進度實際上就是文件流來復制文件,并在每一塊文件復制后,用進度條來顯示復制情況。
一、本實例中主要是以線程和委托的方式,在使用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) 程序運行結果如圖所示:
原文鏈接:https://blog.csdn.net/weixin_44543135/article/details/112915597
相關推薦
- 2023-02-01 Python動態演示旋轉矩陣的作用詳解_python
- 2023-03-17 Docker部署Nginx并修改配置文件的兩種方式_docker
- 2023-01-02 Android?Map數據結構全面總結分析_Android
- 2022-04-15 C語言?使用qsort函數來進行快速排序_C 語言
- 2022-11-17 Go語言學習教程之反射的示例詳解_Golang
- 2022-03-09 C++實現模擬shell命令行(代碼解析)_C 語言
- 2022-05-17 Mybatis中報錯:attempted to return null from a method
- 2022-11-30 react源碼層探究setState作用_React
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支