第一步:什么是序列化和反序列化
序列化定义:将对象转化为容易传输的格式的过程。
反序列化定义:重新解析构造被序列化的对象
第二步:为什么要序列化和反序列化
- 当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再回复为对象。
- 我们经常需要将对象的字段值保存在磁盘中。并在以后检索此数据。尽管不适用序列化也能完成这项工作,单这样方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形:程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。
- NET公共语言运行时(CLR)管理对象在内存中的分布,.NET框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其它实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET框架所提供的序列化体系结构可以自动正确处理对象图标和循环引用。对图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为Serializable。否则,当序列化程序试图序列化未标记的对象时将会出现异常。
第三步:序列化和反序列化方法
NET框架提供了两种串行化的方式:
1、是使用BinaryFormatter进行串行化;
2、使用SoapFormatter进行串行化;
3、使用XmlSerializer进行串行化。
第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储;第三种其实和第二种差不多也是XML的格式存储,只不过比第二种的XML格式要简化很多(去掉了SOAP特有的额外信息)。可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、2可以使用[NonSerialized]属性来标志,2、可以使用[XmlIgnore]来标志。
第四步:实例
1、创建一个可序列化的类
namespace test1
{
[Serializable]
public class Person
{
public string sno { get; set; }
public string name { get; set; }
public string sex { get; set; }
public int age { get; set; }
public string displayInfo()
{
return "我的学号是:" + sno + "\n我的名字是:" + name + "\n我的性别为:" + sex + "\n我的年龄:" + age + "\n";
}
}
}
2、BinaryFormatter序列化方式
private void btn_start_Click(object sender, EventArgs e)
{
Person me = new Person
{
sno = "200719",
name="yyyyyyy",
sex="man",
age=22
};
//创建一个格式化程序实例
IFormatter formatter = new BinaryFormatter();
try
{
//创建一个文件流,如果D盘目录下没有就会自动创建一个此文件
Stream stream = new FileStream("D:/personInfo.txt",FileMode.OpenOrCreate,FileAccess.Write,FileShare.None);
formatter.Serialize(stream, me);
stream.Close();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
执行这个序列化程序后就会在D盘根路径创建一个personInfo.txt文件。
反序列:
private void btn_start_Click(object sender, EventArgs e)
{
//创建一个格式化程序的实例
IFormatter foramtter = new BinaryFormatter();
Stream destream = new FileStream("D:/personInfo.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
var stillme = (Person)foramtter.Deserialize(destream);
Console.WriteLine(stillme.displayInfo());
}
3、SoapFormatter序列化方式
private void btn_start_Click(object sender, EventArgs e)
{
Person me = new Person
{
sno = "200719",
name = "yyyyyyy",
sex = "man",
age = 22
};
//创建一个格式化程序实例
IFormatter formatter = new SoapFormatter();
try
{
//创建一个文件流
Stream stream = new FileStream("c:/personInfo.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, me);
stream.Close();
Console.WriteLine("序列化结束!\n");
Console.WriteLine("反序列化开始……");
//反序列化
Stream destream = new FileStream("c:/personInfo.txt", FileMode.Open,
FileAccess.Read, FileShare.Read);
var stillme = (Person)formatter.Deserialize(destream);
stream.Close();
Console.WriteLine("反序列化结束,输出对象信息……");
Console.WriteLine(stillme.displayInfo());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
4、XML序列化方式
private void btn_start_Click(object sender, EventArgs e)
{
Person me = new Person
{
sno = "200719",
name = "yyyyyyy",
sex = "man",
age = 22
};
//创建一个格式化程序实例
XmlSerializer formatter = new XmlSerializer(typeof(Person));
try
{
//创建一个文件流
Stream stream = new FileStream("c:/personInfo.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, me);
stream.Close();
Console.WriteLine("序列化结束!\n");
Console.WriteLine("反序列化开始……");
//反序列化
Stream destream = new FileStream("c:/personInfo.txt", FileMode.Open,
FileAccess.Read, FileShare.Read);
var stillme = (Person)formatter.Deserialize(destream);
stream.Close();
Console.WriteLine("反序列化结束,输出对象信息……");
Console.WriteLine(stillme.displayInfo());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
结果: