如何在C#中解决System.OutOfMemoryException?

时间:2013-01-16 21:22:10

标签: c# asp.net

我的代码是

     private byte[] Invoke(Stream inputFileStream, CryptoAction action)
     {
        var msData = new MemoryStream();
        CryptoStream cs = null;

        try
        {
            long inputFileLength = inputFileStream.Length;
            var byteBuffer = new byte[4096];
            long bytesProcessed = 0;
            int bytesInCurrentBlock = 0;

            var csRijndael = new RijndaelManaged();
            switch (action)
            {
                case CryptoAction.Encrypt:
                    cs = new CryptoStream(msData, csRijndael.CreateEncryptor(this.Key, this.IV), CryptoStreamMode.Write);
                    break;

                case CryptoAction.Decrypt:
                    cs = new CryptoStream(msData, csRijndael.CreateDecryptor(this.Key, this.IV), CryptoStreamMode.Write);
                    break;
            }

            while (bytesProcessed < inputFileLength)
            {
                bytesInCurrentBlock = inputFileStream.Read(byteBuffer, 0, 4096);
                cs.Write(byteBuffer, 0, bytesInCurrentBlock);
                bytesProcessed += bytesInCurrentBlock;
            }
            cs.FlushFinalBlock();

            return msData.ToArray();
        }
        catch
        {
            return null;
        }
    }

如果加密大小为60mb的大文件,则会抛出System.OutOfMemoryException并导致程序崩溃。我的操作系统是64位且有8Gb的内存。

1 个答案:

答案 0 :(得分:1)

尝试摆脱所有缓冲区管理代码,这可能是导致问题的原因...尝试使用两个流(MemoryStream用于volatile输出很好):

using (FileStream streamInput = new FileStream(fileInput, FileMode.Open, FileAccess.Read))
{
    using (FileStream streamOutput = new FileStream(fileOutput, FileMode.OpenOrCreate, FileAccess.Write))
    {
        CryptoStream streamCrypto = null;
        RijndaelManaged rijndael = new RijndaelManaged();
        cspRijndael.BlockSize = 256;

        switch (CryptoAction)
        {
            case CryptoAction.ActionEncrypt:
                streamCrypto = new CryptoStream(streamOutput, rijndael.CreateEncryptor(this.Key, this.IV), CryptoStreamMode.Write);
                break;

            case CryptoAction.ActionDecrypt:
                streamCrypto = new CryptoStream(streamOutput, rijndael.CreateDecryptor(this.Key, this.IV), CryptoStreamMode.Write);
                break;
        }

        streamInput.CopyTo(streamCrypto);
        streamCrypto.Close();
    }
}