C#實(shí)現(xiàn)對象序列化的三種方式
前言
最近有一些學(xué)員問到了一些關(guān)于序列化的問題,今天這篇文章,跟大家分享一下在C#開發(fā)中,常用的三種序列化的方式。
很多小伙伴一提到序列化,都會想到二進(jìn)制序列化,但其實(shí)序列化并不僅僅只是二進(jìn)制序列化,我們常說的對象序列化有三種方式,分別是二進(jìn)制序列化、XML序列化及JSON序列化,這三種方式各有各自的優(yōu)勢和不足,實(shí)際應(yīng)用中,大家自己根據(jù)實(shí)際情況,選擇適合的。
準(zhǔn)備
在實(shí)現(xiàn)之前,先要做一些準(zhǔn)備工作,序列化其實(shí)是對象和字符串(文件)之間的互相轉(zhuǎn)換,所以首先我們準(zhǔn)備好一個(gè)實(shí)體類,很簡單的Student類:
????public?class?Student
????{
????????public?int?StudentId?{?get;?set;?}
????????public?string?StudentName?{?get;?set;?}
????????public?string?ClassName?{?get;?set;?}
????????public?override?string?ToString()
????????{
????????????return?StudentId?+?";"?+?StudentName?+?";"?+?ClassName;
????????}
????}
這里我重寫了ToString方法,便于后續(xù)測試時(shí),直觀地看到對象的值是否正確。
同時(shí)我們準(zhǔn)備好一個(gè)Student對象,后面就一直要對它進(jìn)行操作了。
????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????Student?student?=?new?Student()
????????????{
????????????????StudentId?=?10001,
????????????????StudentName?=?"小華",
????????????????ClassName?=?"軟件一班"
????????????};
????????}?
????}
二進(jìn)制
二進(jìn)制序列化及反序列化的方式主要是使用BinaryFormatter這個(gè)類,序列化代碼如下:
????BinaryFormatter?serializer?=?new?BinaryFormatter();
????MemoryStream?memStream?=?new?MemoryStream();
????serializer.Serialize(memStream,?student);
????memStream.Close();
????string?info?=?Encoding.Unicode.GetString(memStream.ToArray());
????Console.WriteLine("二進(jìn)制序列化結(jié)果:");
????Console.WriteLine(Environment.NewLine);
????Console.WriteLine(info);
????Console.WriteLine(Environment.NewLine);
反序列化代碼如下:
????memStream?=?new?MemoryStream(Encoding.Unicode.GetBytes(info));
????student?=?(Student)serializer.Deserialize(memStream);
????memStream.Close();
????Console.WriteLine("二進(jìn)制反序列化結(jié)果:");
????Console.WriteLine(Environment.NewLine);
????Console.WriteLine(student.ToString());
????Console.WriteLine(Environment.NewLine);
最終執(zhí)行結(jié)果如下:

我們可以看到二進(jìn)制序列化的結(jié)果是一串亂碼,但是我們可以通過反序列化的方式,拿到轉(zhuǎn)換之后的結(jié)果。
這種方式使用起來比較簡單,甚至還有加密的作用,但是也有一些不足:
類名上面要加上[Serializable],不加無法序列化
????[Serializable]
????public?class?Student
????{
????????public?int?StudentId?{?get;?set;?}
????????public?string?StudentName?{?get;?set;?}
????????public?string?ClassName?{?get;?set;?}
????????public?override?string?ToString()
????????{
????????????return?StudentId?+?";"?+?StudentName?+?";"?+?ClassName;
????????}
????}
序列化的結(jié)果非常大,使用System.Text.Encoding.UTF8.GetString(bytes)查看下,發(fā)現(xiàn)數(shù)據(jù)量很大。
序列化對象需要完全一致,連命名空間都要相同。
XML
XML序列化可提高可讀性,以及對象共享和使用的靈活性,XML序列化將對象的公共字段和屬性或方法的參數(shù)和返回值序列化成符合特定XML格式的流。
XML序列化代碼如下:
????XmlWriterSettings?xmlSettings?=?new?XmlWriterSettings();
????xmlSettings.OmitXmlDeclaration?=?true;
????xmlSettings.Encoding?=?new?System.Text.UTF8Encoding(false);
????MemoryStream?stream?=?new?MemoryStream();
????XmlWriter?xmlwriter?=?XmlWriter.Create(stream,?xmlSettings);?
????XmlSerializerNamespaces?xmlns?=?new?XmlSerializerNamespaces();
????xmlns.Add(String.Empty,?String.Empty);?
????XmlSerializer?ser?=?new?XmlSerializer(typeof(Student));
????ser.Serialize(xmlwriter,?student,?xmlns);
????string?info?=?Encoding.UTF8.GetString(stream.ToArray());
????Console.WriteLine("XML序列化結(jié)果:");
????Console.WriteLine(Environment.NewLine);
????Console.WriteLine(info);
????Console.WriteLine(Environment.NewLine);
XML反序列化代碼如下:
????XmlReader?xmlReader?=?XmlReader.Create(new?StringReader(info),?new?XmlReaderSettings());
????student?=?(Student)new?XmlSerializer(typeof(Student)).Deserialize(xmlReader);
????Console.WriteLine("XML反序列化結(jié)果:");
????Console.WriteLine(Environment.NewLine);
????Console.WriteLine(student.ToString());
????Console.WriteLine(Environment.NewLine);
最終執(zhí)行結(jié)果如下:

我們可以直觀地看到XML序列化的結(jié)果,可讀性增強(qiáng)了很多,但是XML有它自身的不足之處。
JSON
JSON序列化是目前使用很多的一種方式,實(shí)現(xiàn)JSON序列化的方式也有很多,我一般會使用NewSoft.Json這個(gè)庫來做,可以通過Nuget搜索安裝。
JSON序列化代碼如下:
????string?info?=?JsonConvert.SerializeObject(student);
????Console.WriteLine("JSON序列化結(jié)果:"?+?Environment.NewLine);
????Console.WriteLine(info);
????Console.WriteLine(Environment.NewLine);
JSON反序列化代碼如下:
????student?=?(Student)JsonConvert.DeserializeObject(info,?typeof(Student));
????Console.WriteLine("JSON反序列化結(jié)果:");
????Console.WriteLine(Environment.NewLine);
????Console.WriteLine(student.ToString());
????Console.WriteLine(Environment.NewLine);
最終執(zhí)行結(jié)果如下:

我們可以看到JSON的方式除了可讀性增強(qiáng)之外,結(jié)果也更加簡潔。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-END-