2015-08-13 14 views
1

我一直在研究作为项目的一部分来加密和解密文件的程序。该程序本身工作正常,但是当我尝试向其添加进度条以显示加密/解密过程的进度时,事情就会出错。进度条进行得非常好,达到85-90%左右,然后它会抛出错误,指出该值已超过最大限制。此外,条形图执行速度过慢,即使在我正在加密一个16KB文件时也需要大约15-20秒才能到达错误情况,而在没有任何进度条的情况下几乎不需要时间。我曾尝试使用backgroundworker来实现进度条。任何人都可以告诉我如何让进度条工作在我的程序上?如何在c#中的cryptostream写入操作中添加进度条

这里是我的加密过程代码:

public void EncryptFile() 
    { 

     try 
     { 
      OpenFileDialog od = new OpenFileDialog(); 
      od.Title = "Select File To Encrypt"; 
      od.Filter = "All files (*.*)|*.*"; 
      string ifile = ""; 
      if (od.ShowDialog() == DialogResult.OK) 
      { 
       ifile = od.InitialDirectory + od.FileName; 
      } 
      else 
      { 
       MessageBox.Show("No file selected!!"); 
       goto b; 
      } 

      if (Path.GetExtension(ifile) == ".arv") 
      { 
       MessageBox.Show("Error!!File already Encrypted."); 
       return; 
      } 
      string ofile = ifile + ".arv"; 

     a: string password = Prompt.ShowDialog(); 
      if (password == "") 
      { 
       MessageBox.Show("Password Field cannot be blank!!"); 
       goto a; 
      } 
      else if (password == null) 
      { 
       goto b; 
      } 
      int ph = password.GetHashCode(); 
      byte[] ia = BitConverter.GetBytes(ph); 
      if (BitConverter.IsLittleEndian) 
       Array.Reverse(ia); 
      byte[] phb = ia; 

      UnicodeEncoding UE = new UnicodeEncoding(); 
      byte[] salt = new byte[] { 10, 20, 30, 40, 50, 60, 70, 80 }; 
      Rfc2898DeriveBytes k = new Rfc2898DeriveBytes(password, salt); 

      string cryptFile = ofile; 
      FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create); 

      AesManaged AMCrypto = new AesManaged(); 
      AMCrypto.Key = k.GetBytes(32); 
      AMCrypto.IV = k.GetBytes(16); 

      CryptoStream cs = new CryptoStream(fsCrypt, AMCrypto.CreateEncryptor(), CryptoStreamMode.Write); 
      cs.Write(phb, 0, 4); 
      FileStream fsIn = new FileStream(ifile, FileMode.Open); 

      int data; 
      while ((data = fsIn.ReadByte()) != -1) 
       cs.WriteByte((byte)data); 

      fsIn.Close(); 
      cs.Close(); 
      fsCrypt.Close(); 
      File.Delete(ifile); 
      MessageBox.Show("File Encrypted!!"); 
     b: ; 
     } 
     catch (Exception e) 
     { 
      MessageBox.Show(e.ToString()); 
     } 

的提示是我创建的产生,要求用户输入他的密码动态形式的单独的类。它看起来非常像任何带有两个字段的密码提示,用于输入并验证密码和显示密码复选框。 ifile是输入文件,而ofile是输出文件。

更新:这是我用backgroundworker尝试的代码。进度条似乎现在可以工作,但加密速度大大降低,加密过程在填充进度条之前完成,即在进度条填满之前显示“加密完成”消息。此外,当我尝试做同样的事情进行解密时,我收到一个异常说,cryptostream不支持寻求。有任何想法吗?

public Form1() 
    { 
     InitializeComponent(); 
     Shown += new EventHandler(Form1_Shown); 


     backgroundWorker1.WorkerReportsProgress = true; 

     backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); 

     backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); 
    } 
    void Form1_Shown(object sender, EventArgs e) 
    { 

     backgroundWorker1.RunWorkerAsync(); 
    } 
    void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     try 
     { 

      string ifile = @"F:\abc.mp4"; 
      int i = 0; 
      if (Path.GetExtension(ifile) == ".arv") 
      { 
       MessageBox.Show("Error!!File already Encrypted."); 
       return; 
      } 
      string ofile = ifile + ".arv"; 

     a: string password = Prompt.ShowDialog(); 
      if (password == "") 
      { 
       MessageBox.Show("Password Field cannot be blank!!"); 
       goto a; 
      } 
      else if (password == null) 
      { 
       goto b; 
      } 
      int ph = password.GetHashCode(); 
      byte[] ia = BitConverter.GetBytes(ph); 
      if (BitConverter.IsLittleEndian) 
       Array.Reverse(ia); 
      byte[] phb = ia; 

      UnicodeEncoding UE = new UnicodeEncoding(); 
      byte[] salt = new byte[] { 10, 20, 30, 40, 50, 60, 70, 80 }; 
      Rfc2898DeriveBytes k = new Rfc2898DeriveBytes(password, salt); 

      string cryptFile = ofile; 
      FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create); 

      AesManaged AMCrypto = new AesManaged(); 
      AMCrypto.Key = k.GetBytes(32); 
      AMCrypto.IV = k.GetBytes(16); 

      CryptoStream cs = new CryptoStream(fsCrypt, AMCrypto.CreateEncryptor(), CryptoStreamMode.Write); 
      cs.Write(phb, 0, 4); 
      FileStream fsIn = new FileStream(ifile, FileMode.Open); 

      int data; 
      double counter = 1; 
      while ((data = fsIn.ReadByte()) != -1) 
      { 
       cs.WriteByte((byte)data); 
       backgroundWorker1.ReportProgress((int)((counter/fsIn.Length) * 100)); 
       counter++; 
      } 

      fsIn.Close(); 
      cs.Close(); 
      fsCrypt.Close(); 
      File.Delete(ifile); 
      MessageBox.Show("File Encrypted!!"); 
     b: ; 
     } 
     catch (Exception f) 
     { 
      MessageBox.Show(f.ToString()); 
     } 
+3

我看不出有任何的代码在那里的进度条...? –

回答

0

使用BackgroundWorker

int data; 
double counter = 1; 
while ((data = fsIn.ReadByte()) != -1) 
{ 
    cs.WriteByte((byte)data); 
    worker.ReportProgress((int)((counter/fs.Length) * 100)); 
    counter++; 
} 

如果您对如何使用不确定一个BackgroundWorker

C# Progress bar - can't wrap my head around it

+0

嘿,谢谢Ryan.Your解决方案确实有效,但现在我有一个新问题。我已经更新了我的问题。你能帮我吗? – Aman