我们已经理解了如何把一个类型声明为可序列化的类型,但是万里长征只走了第一步,具体完成序列化和反序列化的操作还需要一个执行这些操作的类型。为了序列化具体实例到某种专用的格式,.NET中提供了三种对象序列格式化类型:BinaryFormatter、SoapFormatter和XmlSerializer。.
(1)BinaryFormatter
顾名思义,BinaryFormatter可用于将可序列化的对象序列化成二进制的字节流,在前面Serializable特性的代码示例中已经展示过,这里不再重复展示。
(2)SoapFormatter
SoapFormatter致力于将可序列化的类型序列化成符合SOAP规范的XML文档以供使用。在.NET中,要使用SoapFormatter需要先添加对于SoapFormatter的引用:
using System.Runtime.Serialization.Formatters.Soap;
Note:SOAP是一种位于应用层的网络协议,它基于XML,并且是Web Service的基本协议。
(3)XmlSerializer
XmlSerializer并不仅仅针对那些标记了Serializable特性的类型,更为需要注意的是,Serializable和NonSerialized特性在XmlSerializer类型对象的操作中完全不起作用,取而代之的是XmlIgnore属性。XmlSerializer可以对没有标记Serializable特性的类型对象进行序列化,但是它仍然有一定的限制:
① 使用XmlSerializer序列化的对象必须显示地拥有一个无参数的公共构造方法;
因此,我们需要修改前面代码示例中的Person类,添加一个无参数的公共构造方法:
[Serializable]
public class Person
{
......
public Person()
{
}
......
}
② XmlSerializer只能序列化公共成员变量;
因此,Person类中的私有成员_number便不能被XmlSerializer进行序列化:
[Serializable]
public class Person
{
// 私有成员无法被XmlSerializer序列化
private int _number;
}
(4)综合演示SoapFormatter和XmlSerializer的使用方法:
① 重新改写Person类
[Serializable]
public class Person
{
// 私有成员无法被XmlSerializer序列化
private int _number;
// 使用NonSerialized特性标记此成员不可被BinaryFormatter和SoapFormatter序列化
[NonSerialized]
public string _name;
// 使用XmlIgnore特性标记此成员不可悲XmlSerializer序列化
[XmlIgnore]
public string _univeristy;
public Person()
{
}
public Person(int i, string s, string u)
{
this._number = i;
this._name = s;
this._univeristy = u;
}
public override string ToString()
{
string result = string.Format("学号是:{0},姓名是:{1},大学是:{2}", _number, _name, _univeristy);
return result;
}
}
② 新增SoapFormatter和XmlSerializer的序列化和反序列化方法
#region 01.SoapFormatter
// 序列化对象-SoapFormatter
static byte[] SoapFormatterSerialize(Person p)
{
// 使用Soap协议序列化
IFormatter formatter = new SoapFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms, p);
return ms.ToArray();
}
}
// 反序列化对象-SoapFormatter
static Person SoapFormatterDeSerialize(byte[] data)
{
// 使用Soap协议反序列化
IFormatter formatter = new SoapFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
Person p = formatter.Deserialize(ms) as Person;
return p;
}
}
#endregion
#region 02.XmlSerializer
// 序列化对象-XmlSerializer
static byte[] XmlSerializerSerialize(Person p)
{
// 使用XML规范序列化
XmlSerializer serializer = new XmlSerializer(typeof(Person));
using (MemoryStream ms = new MemoryStream())
{
serializer.Serialize(ms, p);
return ms.ToArray();
}
}
// 反序列化对象-XmlSerializer
static Person XmlSerializerDeSerialize(byte[] data)
{
// 使用XML规范反序列化
XmlSerializer serializer = new XmlSerializer(typeof(Person));
using (MemoryStream ms = new MemoryStream(data))
{
Person p = serializer.Deserialize(ms) as Person;
return p;
}
}
#endregion
③ 改写Main方法进行测试
static void Main(string[] args)
{
Person obj = new Person(26, "Edison Chou", "CUIT");
Console.WriteLine("原始对象为:");
Console.WriteLine(obj.ToString());
// 使用SoapFormatter序列化对象
byte[] data1 = SoapFormatterSerialize(obj);
Console.WriteLine("SoapFormatter序列化后:");
Console.WriteLine(Encoding.UTF8.GetString(data1));
Console.WriteLine();
// 使用XmlSerializer序列化对象
byte[] data2 = XmlSerializerSerialize(obj);
Console.WriteLine("XmlSerializer序列化后:");
Console.WriteLine(Encoding.UTF8.GetString(data2));
Console.ReadKey();
}
示例运行结果如下图所示: