既然每次序列化時,.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; }
}
}
}