2012-05-05 151 views
1

我有一個小應用程序,其中包括其他讀取任何文件(即.exe,.jpg,.img和所有其他文件),將其轉移到bytes[]File.ReadAllBytes(),使用3DES對其進行加密並保存與File.WriteAllBytes()。比做解密方法,做相同的反向。我的問題是,一切工作正常,高達300MB的原始文件,比我有內存不足的例外。任何建議如何解決這個問題?如何處理大於1GB的文件?它可以幫助而使用streamreader或cryptostream讀寫器?File.ReadAllBytes()內存異常

閱讀和加密文件:

try 
{ 
    saveFileDialog1.FileName = ""; 
    DialogResult result = openFileDialog1.ShowDialog(); 
    if (result == DialogResult.OK) 
    { 
     byte[] Results; 
     System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
     fileToEncrypt = File.ReadAllBytes(openFileDialog1.FileName); 
     MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
     byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(textBox1.Text)); 
     TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
     TDESAlgorithm.Key = TDESKey; 
     TDESAlgorithm.Mode = CipherMode.ECB; 
     TDESAlgorithm.Padding = PaddingMode.PKCS7; 
     ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor(); 
     Results = Encryptor.TransformFinalBlock(fileToEncrypt, 0, fileToEncrypt.Length); 
     saveFileDialog1.FileName = openFileDialog1.SafeFileName; 
     saveFileDialog1.ShowDialog(); 
     if (saveFileDialog1.FileName != "") 
     { 
      File.WriteAllBytes(saveFileDialog1.FileName, Results); 
     } 
     TDESAlgorithm.Clear(); 
     HashProvider.Clear(); 
    } 
} 
catch 
{ 
    MessageBox.Show("Your system has not enough memory.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); 
} 

解密和保存:

try 
{ 
    openFileDialog1.FileName = ""; 
    DialogResult result = openFileDialog1.ShowDialog(); 
    if (result == DialogResult.OK) // Test result. 
    { 
     byte[] Results; 
     System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
     fileToDecrypt = File.ReadAllBytes(openFileDialog1.FileName); 
     MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
     byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(textBox1.Text)); 
     TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
     TDESAlgorithm.Key = TDESKey; 
     TDESAlgorithm.Mode = CipherMode.ECB; 
     TDESAlgorithm.Padding = PaddingMode.PKCS7; 
     ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor(); 
     Results = Decryptor.TransformFinalBlock(fileToDecrypt, 0, fileToDecrypt.Length); 
     saveFileDialog1.FileName = Path.GetFileName(openFileDialog1.FileName); 
     saveFileDialog1.ShowDialog(); 
     if (saveFileDialog1.FileName != "") 
     { 
      File.WriteAllBytes(saveFileDialog1.FileName, Results); 
     } 
     TDESAlgorithm.Clear(); 
     HashProvider.Clear(); 
    } 
} 
catch 
{ 
    MessageBox.Show("Master password is wrong", "", MessageBoxButtons.OK, MessageBoxIcon.Error); 
} 

我唯一的愛好編碼,所以我對一些仁與我的代碼:)

textbox1.Text是祈禱主密碼。

+15

不要文件讀入到內存中,只是通過'FileStream'的加密方法 – Magnus

+1

這裏的心理誤區是,你假設加密提供商也流。它不是,它只是一個轉換字節的算法。你沒有使用CrytoStream類。只要按照MSDN例如:http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledescryptoserviceprovider.aspx –

+0

您似乎捕獲所有異常。你怎麼能確定它是一個OutOfMemoryException? –

回答

0

最後我不得不使用CryptoStream的東西 - 我的筆記本上8分鐘加密文件2,7GB。 感謝馬格努斯的努力,我會嘗試你的代碼也

加密方法

DialogResult result = openFileDialog1.ShowDialog(); 
     if (result == DialogResult.OK) 
     { 
      saveFileDialog1.FileName = openFileDialog1.SafeFileName; 
      saveFileDialog1.ShowDialog(); 
      FileStream readFile = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read); 
      FileStream writeFile = new FileStream(saveFileDialog1.FileName, FileMode.OpenOrCreate, FileAccess.Write); 
      writeFile.SetLength(0); 

      byte[] storage = new byte[100]; 
      long fileWritten = 0; 
      long totlen = readFile.Length; 
      int bytesToWrite; 

      System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
      MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
      byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(textBox1.Text)); 
      TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider(); 
      TDES.Key = TDESKey; 
      TDES.Mode = CipherMode.ECB; 
      TDES.Padding = PaddingMode.PKCS7; 
      CryptoStream cryptStream = new CryptoStream(writeFile, TDES.CreateEncryptor(), CryptoStreamMode.Write); 
      while (fileWritten < totlen) 
      { 
       bytesToWrite = readFile.Read(storage, 0, 100); 
       cryptStream.Write(storage, 0, bytesToWrite); 
       fileWritten = fileWritten + bytesToWrite; 

      } 

      cryptStream.Close(); 
      TDES.Clear(); 
      HashProvider.Clear(); 
     } 

解密方法是使用TDES.CreateDecryptor()代替TDES.CreateEncryptor()相同。 我必須說File.ReadAllBytes()File.WriteAllBytes()快得多與文件大小300MB比流。

+0

尺寸100的緩存沒有大小限制的方式小,增加它來獲得性能。至少4096。 – Magnus