VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • C#教程之C#高性能二进制序列化

    二进制序列化可以方便快捷的将对象进行持久化或者网络传输,并且体积小、性能高,应用面甚至还要高于json的序列化;开始之前,先来看看dotcore/dotne自带的二进制序列化:C#中对象序列化和反序列化一般是通过BinaryFormatter类来实现的二进制序列化、反序列化的。

        BinaryFormatter序列化:

复制代码
1 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
2 
3 System.IO.MemoryStream memStream = new System.IO.MemoryStream();
4 
5 serializer.Serialize(memStream, request);
复制代码

        BinaryFormatter反序列化:

复制代码
 1  memStream.Position=0;
 2 
 3  System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserializer =
 4 
 5  new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
 6 
 7  object newobj = deserializer.Deserialize(memStream);
 8 
 9  memStream.Close();
10 
11  return newobj;
复制代码

        用着多了就发现BinaryFormatter有很多地方不妥,下面就来数数这个序列化的“三宗罪”:

        1.类名上面要加上[Serializable],不加不给序列化;正常的用法应该是序列化一个对象,不需的地方加上NonSerialized才合理吧;

        2.序列化byte[]结果非常大,使用System.Text.Encoding.UTF8.GetString(bytes)查看下,发现里面有一大堆的元数据;对比看看google的protobuf,pb为什么在网络上应用的越来越多,这和他本身序列化完后体积小有着绝大部门的原因;

        3.序列化对象需要完全一致,连类的命名空间都要相同,这点对于分面式开发的应用来说也是不可接受的;

        既然BinaryFormatter不好用,那就只能动手自行实现一个解决上述问题的二进制序列化方案;首先去掉[Serializable]这个标签,接着主要是分析对象,并定义对象序列化后的数据结构;这里的想法是按长度加内容的方式来定义,举个例子:使用int作为长度,来保存一个int值,序列化完应该是:4,0,0,0,1,0,0,0这样的一组bytes,同理可以将int、short、long、float、double、datetime、enum、array、string、class、generic等按照这个格式进行序列化,这里主要使用的是BitConverter、反射等来实现序列化与反序列化;

        序列化实现如下:

View Code

        反序列化实现如下:

View Code

        其他详细的代码可以查看ParamsSerializeUtil.cs

        功能基本实现了,下面对比一下10000次的实体序列化与反序列化测试结果:

        实体代码:

复制代码
 1             var groupInfo = new GroupInfo()
 2             {
 3                 GroupID = 1,
 4                 IsTemporary = false,
 5                 Name = "yswenli group",
 6                 Created = DateTimeHelper.Now,
 7                 Creator = new UserInfo()
 8                 {
 9 
10                     ID = 1,
11                     Birthday = DateTimeHelper.Now.AddYears(-100),
12                     UserName = "yswenli"
13                 },
14                 Users = new System.Collections.Generic.List<UserInfo>()
15                 {
16                     new UserInfo()
17                     {
18 
19                         ID = 1,
20                         Birthday = DateTimeHelper.Now.AddYears(-100),
21                         UserName = "yswenli"
22                     }
23                 }
24             };
复制代码

        测试代码:

View Code

        运行结果:



相关教程