带进度条的文件复制。

今天项目要新增一个文件复制的功能,File.Copy() 没有好的用户体验度,所以想到使用进度条。

  1 const Int32 BUFFER_SIZE = 4096;  //每次拷贝4K的文件, 只考虑大于4K的文件
  2         private void Read(string openPath, string savePath, ProgressBar myBar)
  3         {
  4             lock (openPath)
  5             {
  6                 //返回需拷贝文件的流
  7                 Byte[] bytes = null;
  8                 Stream fsRead = new FileStream(openPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  9                 if (fsRead.Length > BUFFER_SIZE)
 10                 {
 11                     bytes = new Byte[BUFFER_SIZE];
 12                     //调用异步读方法将流中的数据写到bytes数组中
 13                     CopyFileModel model = new CopyFileModel();
 14                     model.FileStream = fsRead;
 15                     model.OpenFile = openPath;
 16                     model.SaveFile = savePath;
 17                     model.Bytes = bytes;
 18                     model.Position = 0;
 19                     model.TotalSize = fsRead.Length;
 20                     model.ObjBar = myBar;
 21                     fsRead.BeginRead(bytes, 0, bytes.Length, new AsyncCallback(AsyncCopyFile), model);
 22                 }
 23                 else
 24                 {
 25                     bytes = new Byte[fsRead.Length];
 26                     fsRead.Read(bytes, 0, bytes.Length);
 27                     //将读取的数据添加到新的文件
 28                     FileStream fsWrite = new FileStream(savePath + Path.GetFileName(openPath), FileMode.Append, FileAccess.Write);
 29                     //StreamWriter write = new StreamWriter((Stream)fsWrite, false, System.Text.Encoding.Default);
 30                     fsWrite.Write(bytes, 0, bytes.Length);
 31                     fsWrite.Flush();
 32                     fsWrite.Close();//关闭输出流
 33                     ShowProgressSchedule(myBar, fsRead.Length, 0);//显示进度
 34                     fsRead.Close();  //关闭输入流
 35                     myBar.Visible = false;
 36                 }
 37             }
 38         }
 39 
 40         /// <summary>
 41         /// 读取字节数组完成方法
 42         /// </summary>
 43         private void AsyncCopyFile(IAsyncResult isr)
 44         {
 45             Int32 readLength = 0;
 46             try
 47             {
 48                 lock (isr.AsyncState)
 49                 {
 50                     Stream stream = null;
 51                     CopyFileModel model = (CopyFileModel)isr.AsyncState;
 52                     stream = model.FileStream;
 53 
 54                     readLength = stream.EndRead(isr);//读取完成后游标的位置
 55 
 56                     model.Position += readLength;  //读取数据的当前位置
 57                     //将读取的数据添加到新的文件
 58                     FileStream fsWrite = new FileStream(model.SaveFile + Path.GetFileName(model.OpenFile), FileMode.Append, FileAccess.Write);
 59                     fsWrite.Write(model.Bytes, 0, model.Bytes.Length);
 60                     fsWrite.Flush();
 61                     fsWrite.Close();
 62                     //在界面上显示progress的进度
 63                     ShowProgressSchedule((ProgressBar)model.ObjBar, model.TotalSize, model.Position);
 64                     //数据拷贝完成
 65                     if (model.Position >= model.TotalSize)
 66                     {
 67                         stream.Close();
 68                         ((ProgressBar)model.ObjBar).Visible = false;
 69                         return;
 70                     }
 71                     Int64 leftSize = model.TotalSize - model.Position;//获得未读数据的字节大小
 72                     if (leftSize < BUFFER_SIZE)
 73                     {
 74                         model.Bytes = new Byte[leftSize];
 75                     }
 76 
 77                     //调用异步读取函数
 78                     stream.BeginRead(model.Bytes, 0, model.Bytes.Length, new AsyncCallback(AsyncCopyFile), model);
 79                 }
 80             }
 81             catch (Exception ex)
 82             {
 83                 throw ex;
 84             }
 85         }
 86 
 87         delegate void ShowProgressScheduleDele(ProgressBar myBar, Int64 totalSize, Int64 position);
 88         private void ShowProgressSchedule(ProgressBar myBar, Int64 totalSize, Int64 position)
 89         {
 90             try
 91             {
 92                 lock (myBar)
 93                 {
 94                     // 判断是否在线程中访问      
 95                     if (!myBar.InvokeRequired)
 96                     {
 97                         // 不是的话直接操作控件
 98                         myBar.Maximum = (Int32)totalSize;
 99                         myBar.Value = (Int32)position;
100                     }
101                     else
102                     {
103                         // 是的话启用delegate访问
104                         ShowProgressScheduleDele showProgress = new ShowProgressScheduleDele(ShowProgressSchedule);
105                         // 如使用Invoke会等到函数调用结束,而BeginInvoke不会等待直接往后走
106                         this.BeginInvoke(showProgress, new object[] { myBar, totalSize, position });
107                     }
108                 }
109             }
110             catch (Exception ex)
111             {
112                 throw ex;
113             }
114         }

调用:

String savePath = @"\\picserver\pack\data\";  //保存文件的路径
        String openPath1 = @"\\dltfile01\pack\data\bg6_yz.dbf";  //打开文件的路径
        String openPath2 = @"\\dltfile01\pack\data\bg6_yz.cdx";  //打开文件的路径
        private void uButton5_Click(object sender, EventArgs e)
        {
            try
            {
                if (File.Exists(openPath1) && File.Exists(openPath2))
                {
                    File.Delete(savePath + "bg6_yz.dbf");
                    File.Delete(savePath + "bg6_yz.cdx");
                    this.progressBar1.Visible = true;
                    this.progressBar2.Visible = true;
                    Read(openPath1, savePath, this.progressBar1);
                    Read(openPath2, savePath, this.progressBar2);
                }
                else
                {
                    UMessageBox.Show("找不到目标文件路径!");
                }
            }
            catch (Exception ex)
            {
                UMessageBox.Show("复制文件时出现以下错误:\r\n" + ex);
                this.progressBar1.Visible = false;
                this.progressBar2.Visible = false;
            }
        }

 

转载于:https://www.cnblogs.com/billt/archive/2013/06/14/3135213.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值