一個問題:
程序在運行的時候,內存中有一個對象,如果你想把這個對象的某些信息或者所有信息保存在本地,下次程序打開后,能夠直接還原這個對象,怎么才能做到呢?或者,如果想把這個對象通過網絡傳遞到另一個程序中,並且讓接收到數據的那個程序能直接通過接收到的數據,還原出一個對象,怎么才能做到呢?
原始方案:我們把對象的信息拼接成一個字符串,即如果名為 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序列化,不作介紹了。