以下是一段MSDN中的代码    public static void EncryptTextToFile(String Data, String FileName, byte[] Key, byte[] IV)
    {
        try
        {
            // Create or open the specified file.
            FileStream fStream = File.Open(FileName, FileMode.OpenOrCreate);            // Create a new Rijndael object.
            Rijndael RijndaelAlg = Rijndael.Create();            // Create a CryptoStream using the FileStream 
            // and the passed key and initialization vector (IV).
            CryptoStream cStream = new CryptoStream(fStream,
                RijndaelAlg.CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);            // Create a StreamWriter using the CryptoStream.
            StreamWriter sWriter = new StreamWriter(cStream);            try
            {
                // Write the data to the stream 
                // to encrypt it.
                sWriter.WriteLine(Data);
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: {0}", e.Message);
            }
            finally
            {
                // Close the streams and
                // close the file.
                sWriter.Close();
                cStream.Close();
                fStream.Close();
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine("A file error occurred: {0}", e.Message);
        }    }让我郁闷的是,为什么三个Stream对象的Close()调用是放在第二个try块里的,如果在第一个try中的
“StreamWriter sWriter = new StreamWriter(cStream);”发生异常,那么,前两个Stream对象不就无法Close下面这段是自已写的代码,异常测试的结果也很让人郁闷using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Diagnostics;namespace TryTest
{
    class DesTest
    {
        public static string Test()
        {
            //Key设置
            byte[] key = Encoding.UTF8.GetBytes("12345678");
            //IV设置
            byte[] iv = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
            //待解密数据
            byte[] value = Convert.FromBase64String("Btf5QTYSUiNGimws8DE3n5EIYNwkJZqW");            //创建des对象
            DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 
            
            //内存六
            MemoryStream mStream = null;
            //解密流
            CryptoStream cStream = null;
            //流Reader
            StreamReader sReader = null;
            
            //返回值
            string retString = string.Empty;
            try
            {                mStream = new MemoryStream(value); //创建内存流,并存入待解密数据
                //throw new Exception("err"); //在这里抛出一个异常,正常                cStream = new CryptoStream(mStream, des.CreateDecryptor(key, iv), CryptoStreamMode.Read); //将内存流包装到解密流
                //throw new Exception("err"); //在这里抛出一个异常,finally出错                sReader = new StreamReader(cStream); //将解密流包装到Reader
                //throw new Exception("err"); //在这里抛出一个异常,finally出错                retString = sReader.ReadToEnd(); //读出解密数据
                //throw new Exception("err"); //在这里抛出一个异常,正常            }
            catch(Exception e)
            {
                Trace.WriteLine(e.Message);
                
            }
            finally
            {
                if (sReader != null)
                    sReader.Close();                if (cStream != null)
                    cStream.Close();                if (mStream != null)
                    mStream.Close();
            }            return retString;
        }
    }
}我用一个try块包住了所有处理代码,然后根据null来Close流,让手动加入throw进行异常测试的结果却让人郁闷,求解!

解决方案 »

  1.   

    这可能也算是CryptoStream的一个BUG
    如果CryptoStream的内容没有全部读出前关闭流的话,就会出错,解决办法:
                finally
                {                if (sReader != null && sReader.BaseStream != null)
                    {
                        sReader.ReadToEnd();
                        sReader.Close();
                    }                if (cStream != null)
                    {
                        while (cStream.ReadByte() != -1)
                        {
                            cStream.ReadByte();
                        }                    cStream.Close();
                    }                if (mStream != null)
                    {
                        mStream.Close();
                    }
                }
      

  2.   

    楼上的高见啊,怎么会有这种情况发生呢郁闷,另外第一段MSDN里的那段代码,哪位能说一下,为什么close要放在第二个try块中
      

  3.   

    很简单,只有sWriter.WriteLine(Data); 
    才会触发异常,其他之前的代码不会触发错误
      

  4.   

    再说MSDN上的代码只是示例,并不保证完美,第一段代码就不见得完美
      

  5.   

    一楼的代码改进一个
                finally
                {
                    if (sReader != null)
                        sReader.Close();
                    if (cStream != null)
                    {
                        while (cStream.ReadByte() != -1) ;
                        cStream.Close();
                    }                if (mStream != null)
                        mStream.Close();
                }只需要把cStream的数据读完就可以了,StreadReader不存在这样的问题
      

  6.   

    在关联了cStream的情况下,sReader.Close()也会作点什么,虽然StreamReader.Close()本身没有这个bug
      

  7.   

    StreamReader.Close()调用是会调用基础类的Close()方法,即cStream.close()