也许是谭大哥给我启示,我本着知其然更要知其所以然的思想开始了本书的历程。不求快,只求益。
当我读到GZipStream对PageState进行压缩的时候,我就傻了。短短十几行代码给了我十几个问号(不要笑,我是初学者)。下面贴出这段代码,也许有和我一样看不懂的,呵呵。


/// <summary>
/// 解压并反序列化状态内容
/// </summary>
/// <param name="stateString">从客户端取回的页面状态字符串</param>
/// <returns>还原后的页面状态Pair对象</returns>
public static object Decompress(string stateString)
{
//先把取回的状态字符串转回压缩后的数组
byte[] buffer = Convert.FromBase64String(stateString);
//解压
MemoryStream ms = new MemoryStream(buffer);
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
MemoryStream msReader = new MemoryStream();
buffer = new byte[0x1000];
while (true)
{
int read = zipStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
msReader.Write(buffer, 0, read);
}
zipStream.Close();
ms.Close();
msReader.Position = 0;
buffer = msReader.ToArray();
stateString = Convert.ToBase64String(buffer);
//反序列化
return _formatter.Deserialize(stateString);
}


/// <summary>
/// 序列化并压缩状态内容
/// </summary>
/// <param name="state">页面状态</param>
/// <returns>结果字符串</returns>
public static string Compress(object state)
{
StringWriter writer = new StringWriter();
//序列化状态
_formatter.Serialize(writer, state);
//取得序列化结果
string stateString = writer.ToString();
writer.Close();
//压缩序列化状态
byte[] buffer = Convert.FromBase64String(stateString);
MemoryStream ms = new MemoryStream();
GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
zipStream.Write(buffer, 0, buffer.Length);
zipStream.Close();
buffer = new byte[ms.Length];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
ms.Close();
//将压缩结果转成Base64字符串,以便存到页面中
stateString = Convert.ToBase64String(buffer);
return stateString;
}
我分析了下,是我对IO框架了解不够。收集些了资料,经过分析,终于有的思想了。先看张IO框架图,一图胜万言。

点击放大
Stream 类,MSDN解释,Provides a generic view of a sequence of bytes. 就是有序的字节。
整个继承Stream类系列,采用了Decorator设计模式,当然有的是直接继承,有的是Decorator类。

有关这个设计模式的详细叙述,请看TrerryLee的 Decorator设计模式
在代码
//
解压
MemoryStream ms = new MemoryStream(buffer);
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
中,如果看完了Decorator模式,就很好理解了。在反编译代码中,GZipStream有个属性property(DeflateStream Class),DeflateStream Class于Stream类关系就是继承关系,于MemoryStream类是装饰关系。GZipStream的属性类DeflateStream在MemoryStream上加了压缩算法。
MemoryStream ms = new MemoryStream(buffer);
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
public
class
GZipStream : Stream
{
private DeflateStream deflateStream;
}
public class DeflateStream : Stream
{
private Stream _stream;
}
{
private DeflateStream deflateStream;
}
public class DeflateStream : Stream
{
private Stream _stream;
}
搞清了之后,再寻“道”。
FileSteam,MemoryStream是基于存放数据的介质不同,一个文件,一个是backing store。
以前搞不清楚TextWriter,TextReader,和Stream类关系,现从IO框图和反编译代码中发现他们作为基类没有任何关系。
他们的子类StringWriter和StringReader简直就是对String的处理类,只有StreamWriter和StreamReader都用到Stream类作为参数。
如果要把string于文件介质发生关系,就传FileStream给StreamWriter和StreamReader,
若要和backing store介质发生关系,就传MemoryStream给StreamWriter和StreamReader,可以类推。
当然上面的规律应该也适合BinaryReader和BinaryWriter。
File静态类有Create方法创建FileStream实例。
。。。等等。我想可以结合IO框架图和反编译源代码一一理清关系。有了一定关系,就不用复制别人的代码,而不假思索了。呵呵。