一个问题:
程序在运行的时候,内存中有一个对象,如果你想把这个对象的某些信息或者所有信息保存在本地,下次程序打开后,能够直接还原这个对象,怎么才能做到呢?或者,如果想把这个对象通过网络传递到另一个程序中,并且让接收到数据的那个程序能直接通过接收到的数据,还原出一个对象,怎么才能做到呢?
原始方案:我们把对象的信息拼接成一个字符串,即如果名为 BeautifulGirl 的类包括三个属性,分别是“name,sex,age”,我们可以拼接一个字符串“name=小丽;sex=女;age=22;”来表示某个对象,保存到本地或者传递给另外一个程序。如果想把这个字符串还原为对象,我们先实例化一个对象,然后解析该字符串,分割,获取出来三个值,分别赋值给BeautifulGirl的这个对象,完成!
这样做也能完成任务,但是弊端太多。如果对象有个Friend属性也是BeautifulGirl类型的,显然,就很不好拼接这个字符串。并且,如果字符串拼写出现一点小小的错误,程序就会出错。有没有更好的办法呢?序列化就该出场了!
序列化就是把一个内存中的对象的信息转化成一个可以持久化保存的形式,以便于保存或传输。
用的比较多的就是XML序列化和JSON序列化。
如果把刚才的对象序列化为XML格式,就是这种形式
<?xml version="1.0"?>
<BeautifulGirl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>小丽</name>
<sex>女</sex>
<age>22</age>
</BeautifulGirl>
如果把刚才的对象序列化为JSON格式,就是这种形式
{"name":"小丽","sex":"女","age":"22"}
现在的很多技术都可以很方便地用这两种格式实现序列化和反序列化,我下面演示一下用C#语言的实现。
XML序列化
引入命名空间 using System.Xml.Serialization;
using System.IO;
这种是转化为XML字符串的形式便于传输
/// <summary>
/// 对象序列化成 XML String
/// </summary>
public string XmlSerialize<T>(T obj)
{
string xmlString = string.Empty;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
xmlSerializer.Serialize(ms, obj);
xmlString = Encoding.UTF8.GetString(ms.ToArray());
}
return xmlString;
}
/// <summary>
/// XML String 反序列化成对象
/// </summary>
public T XmlDeserialize<T>(string xmlString)
{
T t = default(T);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (Stream xmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)))
{
using (XmlReader xmlReader = XmlReader.Create(xmlStream))
{
Object obj = xmlSerializer.Deserialize(xmlReader);
t = (T)obj;
}
}
return t;
}
这一种是序列化为XML文档的形式,便于保存
/// <summary>
/// 二进制序列化
/// </summary>
public static void BinarySerializ(MySerializ mySerializ)
{
using (FileStream stream = new FileStream(@"D:\test.dat", FileMode.Create, FileAccess.Write))
{
BinaryFormatter binary = new BinaryFormatter();
binary.Serialize(stream, mySerializ);
Console.WriteLine("已经序列化。。。");
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
}
}
/// <summary>
/// 二进制反序列化
/// </summary>
public static void BinaryDeserializ(string fileName)
{
using (FileStream stream = new FileStream(fileName,FileMode.Open,FileAccess.Read))
{
BinaryFormatter binary = new BinaryFormatter();
MySerializ mySerializ = (MySerializ)binary.Deserialize(stream);
Console.WriteLine(mySerializ.ToString());
}
}
下面是JSON序列化
引入命名空间: using System.Runtime.Serialization.Json;
/// <summary>
/// JSON序列化
/// </summary>
public static string JsonSerializer<T>(T t)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, t);
string jsonString = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
return jsonString;
}
/// <summary>
/// JSON反序列化
/// </summary>
public static T JsonDeserialize<T>(string jsonString)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj = (T)ser.ReadObject(ms);
return obj;
}
还有二进制序列化和SOAP序列化,不作介绍了。