以下是一段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进行异常测试的结果却让人郁闷,求解!
运行过 cStream = new CryptoStream(mStream, des.CreateDecryptor(key, iv), CryptoStreamMode.Read); 之后,
会有异常====>> Stream does not support seeking.
Length = 'cStream.Length' threw an exception of type 'System.NotSupportedException'
我看了一下
StreamWriter 类的构造函数源码,它做的工作就是简单的将stream 赋值给一个成员变量,并且开一个不大的buf空间。绝大多数情况下这种操作是无法触发异常的,除非内存就差那么一点点内存就耗尽了,如果真的是这样,后面那些语句是否能正常执行也值得怀疑。
另外即使不主动close,GC 在销毁前也会close
如果new的时候就出问题了,那些变量都会是null,好好想想吧。