使用C#在进度条中显示复制文件的进度

来源:互联网 发布:北京java招聘(济南) 编辑:程序博客网 时间:2024/04/19 09:06

#region Using Directives
using System;
using System.IO ;
using System.Xml ;
using System.Collections ;
using System.Reflection ;
using System.Text ;
using System.Data ;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.Threading ;
#endregion

namespace WindowsApplication4
{
 /// <summary>
 /// Copy Large File
 /// </summary>

 public class frmMain : System.Windows.Forms.Form
 {
  #region
  private System.Windows.Forms.ProgressBar progressBar1;
  private System.Windows.Forms.Button btnCopy;
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>

  private System.ComponentModel.Container components = null;

  public frmMain()
  {
   //
   // Windows 窗体设计器支持所必需的
   //

   InitializeComponent();

   //
   // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
   //

  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if (components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Initialize Components
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>

  private void InitializeComponent()
  {
   this.progressBar1 = new System.Windows.Forms.ProgressBar();
   this.btnCopy = new System.Windows.Forms.Button();
   this.SuspendLayout();
   //
   // progressBar1
   //

   this.progressBar1.Location = new System.Drawing.Point(8, 16);
   this.progressBar1.Name = "progressBar1";
   this.progressBar1.Size = new System.Drawing.Size(208, 16);
   this.progressBar1.TabIndex = 0;
   //
   // btnCopy
   //

   this.btnCopy.Location = new System.Drawing.Point(8, 48);
   this.btnCopy.Name = "btnCopy";
   this.btnCopy.TabIndex = 1;
   this.btnCopy.Text = "Copy";
   this.btnCopy.Click += new System.EventHandler(this.btnCopy_Click);
   //
   // frmMain
   //

   this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
   this.ClientSize = new System.Drawing.Size(232, 77);
   this.Controls.Add(this.btnCopy);
   this.Controls.Add(this.progressBar1);
   this.Name = "frmMain";
   this.Text = "Copy File";
   this.ResumeLayout(false);

  }
  #endregion

  /// <summary>
  /// Entry Point
  /// </summary>

  [STAThread]
  static void Main()
  {
   Application.Run(new frmMain());
  }


  #endregion

  int totalSize;  //Total Size
  int position;   //Position
  const int BUFFER_SIZE = 4096;
  byte[] buffer;
  Stream stream;

  private void btnCopy_Click(object sender, System.EventArgs e)
  {
   string strFile = "";

   OpenFileDialog dlg = new OpenFileDialog();
   if ( dlg.ShowDialog() ==  DialogResult.OK )
   {
    strFile = dlg.FileName ;
   }
   else
   {
    return ;
   }

   FileStream fs = new FileStream( strFile , FileMode.Open , FileAccess.Read ) ;
   totalSize = (int)fs.Length ;
   stream = fs;

   //Delete file which aready exists.
   if ( File.Exists( "c://copyedFile.bin" ) )
    File.Delete( "c://copyedFile.bin" );
 
   //Copy file while larger than 4KB.
   if ( totalSize > BUFFER_SIZE )
   {
    buffer = new byte[ BUFFER_SIZE ];

    // Async Invoke
    stream.BeginRead( buffer , 0 , BUFFER_SIZE , new AsyncCallback( AsyncCopyFile ) , null );  
   }
   else
   {
    fs.Close();
   }
   
  }
       
  /// <summary>
  /// Asynchronously copy file
  /// </summary>
  /// <param name="ar"></param
>
  private void AsyncCopyFile( IAsyncResult ar )
  {
   int readedLength ;
   
   // Lock FileStream
   lock( stream )
   {
    readedLength = stream.EndRead( ar );   // When stream endread, get readed length
   }

   // Write to disk
   FileStream fsWriter = new FileStream( "C://copyedFile.bin" , FileMode.Append , FileAccess.Write );
   fsWriter.Write( buffer , 0 , buffer.Length );
   fsWriter.Close();
 
   // Current stream position
   position += readedLength;
    
   // Response UI
   MethodInvoker m = new MethodInvoker( SynchProgressBar );
   m.BeginInvoke( null , null );
 
   if ( position >= totalSize ) // Read over.
   {
    stream.Close();        //Close FileStream 
    return ;
   }

   // Continue to read and write
   lock ( stream )
   {
    int leftSize = totalSize - position;

    if ( leftSize < BUFFER_SIZE )
     buffer = new byte[ leftSize ];

    stream.BeginRead( buffer , 0 , buffer.Length , new AsyncCallback( AsyncCopyFile ) , null );    
     
   }
  }

  private void SynchProgressBar()
  {
   this.progressBar1.Maximum = totalSize;
   this.progressBar1.Value   = position ;
  }

 }
}