既然每次序列化时,.net都会动态生成程序集,那么这个过程必然会影响程序效率。而实际上,当类型确定后,那么该程序集的内容也就确定了。所以,能否有一个工具来产生该程序集,然后,程序直接引用它,岂不解决了效率问题?
目前,在.net 2.0中,已经提供了这样的工具(XML Serializer Generator Tool)sgen.exe。但.net 1.1中没有该工具。下面给出了一种半自动的方法:
使用SpeedSerializer的步骤:
1.将Xml序列化开关打开,即:将下面的内容放入执行程序的配置文件中。
<system.diagnostics>
<switches>
<add name="XmlSerialization.Compilation" value="4" />
</switches>
</system.diagnostics>
2.运行原始的XmlSerializer的构造函数(将序列化对象的类型传入),便可从当前帐户的临时目录中,获取到需要序列化类型的IO文件(*.cs)
3.将该文件和SpeedSerializer.cs引入到工程中
4.如果要序列化的对象的类型还未引入工程,那么将其引入
5.将该文件中的Writer类的基类替换成XmlSpeedSerializationWriter;
将该文件中的Reader类的基类替换成XmlSpeedSerializationReader
6.序列化:实例化Writer类,调用其Write方法
反序列化:实例化Reader类,调用其Read方法
SpeedSerializer.cs的源代码如下:
using System;
using System.Xml;
using System.IO;
using System.Reflection;
namespace Core.Service.XmlSerializer
{
public abstract class XmlSpeedSerializationWriter : System.Xml.Serialization.XmlSerializationWriter
{
public XmlSpeedSerializationWriter(){}
public XmlSpeedSerializationWriter(Stream s)
{
this.Init(s);
}
public XmlSpeedSerializationWriter(string fileName)
{
this.Open(fileName);
}
private void Init(Stream s)
{
this.Writer = new XmlTextWriter(s, System.Text.Encoding.GetEncoding(936));
XmlTextWriter xw = this.Writer as XmlTextWriter;
xw.Formatting = Formatting.Indented;
}
public void Close()
{
if(this.Writer != null)
this.Writer.Close();
}
/// <summary>
/// 序列化对象
/// </summary>
/// <param name="fileName">要保存的目标文件的名称</param>
/// <param name="o">序列化的对象</param>
/// <param name="method">IO文件中的根元素对应的方法名称</param>
public void Write(string fileName, object o, string method)
{
FileStream fs = new FileStream(fileName, FileMode.Create);
this.Init(fs);
this.GetType().InvokeMember(method, BindingFlags.InvokeMethod, null, this, new object[]{o});
this.Close();
}
private void Open(string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Create);
this.Init(fs);
}
}
public abstract class XmlSpeedSerializationReader : System.Xml.Serialization.XmlSerializationReader
{
XmlReader reader;
public XmlSpeedSerializationReader(){}
public XmlSpeedSerializationReader(Stream s)
{
this.Init(s);
}
public XmlSpeedSerializationReader(string fileName)
{
Open(fileName);
}
private void Init(Stream s)
{
reader = new XmlTextReader(s);
InitIDs();
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="fileName">目标文件名称</param>
/// <param name="method">IO文件中的读取根元素的方法名称</param>
/// <returns>反序列化的对象</returns>
public object Read(string fileName, string method)
{
this.Open(fileName);
object o = this.GetType().InvokeMember(method, BindingFlags.InvokeMethod, null, this, null);
this.Close();
return o;
}
private void Open(string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Open);
this.Init(fs);
}
private void Close()
{
if(this.Reader != null)
this.Reader.Close();
}
protected new bool ReadNull (){ return false; }
protected new XmlQualifiedName GetXsiType(){ return null; }
protected new void ReadEndElement(){}
protected new XmlReader Reader
{
get{ return this.reader; }
}
}
}