参考链接:
C#序列化与反序列化(Serializable and Deserialize)
二进制序列化的优点:
1. 所有的类成员(包括只读的)都可以被序列化;
2. 性能非常好。
XML序列化的优点:
1. 互操作性好;
2. 不需要严格的二进制依赖;
3. 可读性强。
下面的示例演示了,通过BinaryFormatter和XmlSerializer对对象进行(二进制和XML两种方式的)序列化和反序列化:
using System;
using System.Xml.Serialization;
using System.IO;
using System.Xml.Linq;
using System.Runtime.Serialization.Formatters.Binary;
namespace 序列化和反序列化
{
[Serializable]
public class Radio
{
private string _radioID = string.Empty;
private bool _hasTweeters; // 扩音器
[NonSerialized]
public string Brand = string.Empty;
[XmlIgnore]
public string RadioID
{
get
{
return _radioID;
}
}
public bool HasTweeters
{
get { return _hasTweeters; }
set { _hasTweeters = value; }
}
/// <summary>
/// ctor.
/// </summary>
/// <remarks>
/// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
/// </remarks>
public Radio() { }
public Radio(string radioID, bool hasTweeters)
{
_radioID = radioID;
_hasTweeters = hasTweeters;
Brand = "Panasonic";
}
}
[Serializable]
public class Car
{
public Radio radio { set; get; }
public string Carname { set; get; }
public string OwnerOfCar { set; get; }
public virtual void Print()
{
Console.WriteLine("Carname = '{0}'", this.Carname);
Console.WriteLine("OwnerOfCar = '{0}'", this.OwnerOfCar);
Console.WriteLine("Radio.radioID = '{0}'", this.radio.RadioID);
Console.WriteLine("Radio.hasTweeters = '{0}'", this.radio.HasTweeters);
Console.WriteLine("Radio.Brand = '{0}'", this.radio.Brand);
}
/// <summary>
/// ctor.
/// </summary>
/// <remarks>
/// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
/// </remarks>
public Car() { }
}
[Serializable]
public class ChineseCar : Car
{
public int MaxSpeed { set; get; }
[XmlAttribute]
public bool CanFly { set; get; } // CanFly作为xml属性存储
public override void Print()
{
base.Print();
Console.WriteLine("MaxSpeed = '{0}'", this.MaxSpeed);
Console.WriteLine("CanFly = '{0}'", this.CanFly);
}
/// <summary>
/// ctor.
/// </summary>
/// <remarks>
/// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
/// </remarks>
public ChineseCar() { }
}
class Program
{
/// <summary>
/// 序列化到xml中
/// </summary>
/// <param name="obj">持久化对象</param>
/// <param name="filename">文件名</param>
static void SerializeToXML(object obj, string filename)
{
XmlSerializer formatter =
new XmlSerializer(typeof(ChineseCar), new Type[] { typeof(Radio), typeof(Car) });
using (FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
try
{
Console.WriteLine("Beginning Serialize...");
formatter.Serialize(stream, obj);
Console.WriteLine("Success");
Console.WriteLine("----------------------");
}
catch
{
Console.WriteLine("Serialize fail!");
}
}
}
/// <summary>
/// 从XML中反序列化
/// </summary>
/// <param name="filename">文件名</param>
static object DeSerializeFormXML(string filename)
{
object obj = null;
using (FileStream stream = new FileStream(filename, FileMode.Open))
{
try
{
//formatter = new XmlSerializer(typeof(ChineseCar), new Type[] { typeof(Radio), typeof(Car) });
XmlSerializer formatter = new XmlSerializer(typeof(ChineseCar));
Console.WriteLine("Beginning Deserialize...");
obj = formatter.Deserialize(stream) as ChineseCar;
Console.WriteLine("Success");
Console.WriteLine("----------------------");
}
catch
{
Console.WriteLine("Deserialize fail!");
}
finally
{
stream.Close();
}
}
return obj;
}
/// <summary>
/// 读取xml
/// </summary>
/// <param name="filename">文件名</param>
static void ShowXmlFile(string filename)
{
XElement root = XElement.Load(filename);
Console.WriteLine(root);
}
/// <summary>
/// 序列化到二进制文件
/// </summary>
/// <param name="obj">持久化对象</param>
/// <param name="filename">文件名</param>
static void SerializeToBinary(object obj,string filename)
{
using (Stream stream = File.Open(filename, FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
Console.WriteLine("Beginning Serialize by Binary...");
formatter.Serialize(stream, obj);
Console.WriteLine("Success");
Console.WriteLine("----------------------");
}
}
/// <summary>
/// 从二进制文件中反序列化
/// </summary>
/// <param name="filename">文件名</param>
/// <returns>返回反序列化的对象</returns>
static object DeSerializeFormBinaryFile(string filename)
{
object obj = null;
using (Stream stream = File.Open(filename, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
Console.WriteLine("Beginning Deserialize by Binary...");
obj = (ChineseCar)formatter.Deserialize(stream);
Console.WriteLine("Success");
Console.WriteLine("----------------------");
}
return obj;
}
static void Main(string[] args)
{
ChineseCar obj = new ChineseCar()
{
CanFly = false,
MaxSpeed = 200,
Carname = "flying man",
OwnerOfCar = "bobby",
radio = new Radio("XX-BOBBY734", true)
};
SerializeToXML(obj, "Data.xml"); // XML序列化
Console.WriteLine("输出xml文档内容:");
ShowXmlFile("Data.xml");
Console.WriteLine("----------------------");
ChineseCar cc = DeSerializeFormXML("Data.xml") as ChineseCar; // XML反序列化
cc.Print();
Console.WriteLine("----------------------");
Console.WriteLine();
SerializeToBinary(obj, "BinaryFile"); //二进制序列化
Console.WriteLine("输出Binary文档内容:");
Console.WriteLine("----------------------");
ChineseCar cc1 = DeSerializeFormBinaryFile("BinaryFile") as ChineseCar; // 二进制反序列化
cc1.Print();
Console.ReadLine();
}
}
}
请注意下面这段代码:
[Serializable]
public class Radio
{
private string _radioID = string.Empty;
private bool _hasTweeters; // 扩音器
[NonSerialized]
public string Brand = string.Empty;
[XmlIgnore]
public string RadioID
{
get
{
return _radioID;
}
}
public bool HasTweeters
{
get { return _hasTweeters; }
set { _hasTweeters = value; }
}
/// <summary>
/// ctor.
/// </summary>
/// <remarks>
/// 1.要序列化的类必须有默认的构造的构造函数,才能使用XmlSerializer序列化
/// </remarks>
public Radio() { }
public Radio(string radioID, bool hasTweeters)
{
_radioID = radioID;
_hasTweeters = hasTweeters;
Brand = "Panasonic";
}
}
XmlIgnore描述的RadioID属性将在XmlSerializer持久化时被限制。在输出结果中能看到,Radio.radioID = ’ ‘,说明在XML序列化的时候忽略了对该字段的持久化,这点在生成的XML文档中也能够看到。
NonSerialized修饰Brand字段,将在使用BinaryFormatter持久化时被限制。在输出结果中可以看到Radio.Brand=’ ’
输出结果: