• Serialization全解析


      1 Serialization即序列化,序列化是可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本。
      2 
      3 Remoting和Web Service就是序列化的典型的应用,通过序列化将一个对象从一个应用程序域,发送到另一个应用程序域。
      4 
      5 序列化类默认的情况下是要求他的所有的成员都是要可序列化的(除事件、委托、显式定义不可序列化),对于不想被序列化的成员要声明不可序列化把它加上 [NonSerialized]属性告诉.NET这个类不要被序列化,这样在序列化的时候就不会保存对象的状态。
      6 
      7 下面就将常用的几种序列化方式一一实现出来给大家看一下!
      8 
      9 首先需要新建一个被实例化的类:Person.cs
     10 
     11 namespace SerializationTest
     12 {
     13     [Serializable]//此属性标记为该类可以实例化
     14     [XmlRoot("Hello")]//标记为XML文档的根节点名字
     15     public  class Person<T>
     16     {
     17        [XmlAttribute("Name")]/标记为XML文档属性名
     18       public string Name
     19        {
     20            get;
     21            set;
     22        }
     23       [XmlAttribute("Sex")] 
     24       public string Sex
     25       {
     26           get;
     27           set;
     28       }
     29       [XmlAttribute("Age")]
     30       public int Age
     31       {
     32           get;
     33           set;
     34       }
     35       [NonSerialized]//此属性标记为不可序列化
     36       Work w;
     37       public Work W
     38       {
     39           get
     40           {
     41               return w;
     42           }   
     43           set
     44           {
     45               w = value;
     46           }
     47       }
     48     }
     49       
     50     public class Work
     51     {
     52           [XmlAttribute("WorkName")]
     53         public string WorkName
     54         {
     55             get;
     56             set;
     57         }
     58     }
     59 
     60 
     61 下面开始介绍常使用的几种序列化的方法
     62 
     63 一、BinaryFormatter
     64 
     65 在使用之前需要先引入命名空间:
     66 
     67 using System.Runtime.Serialization;
     68 using System.Runtime.Serialization.Formatters;
     69 using System.Runtime.Serialization.Formatters.Binary;
     70 
     71 具体的实现方法如下:
     72 
     73  //BinaryFormatter方式序列化
     74         private static void Serializable(Person<Work> p)
     75         {
     76             IFormatter formatter = new BinaryFormatter();
     77             //创建文件流
     78             Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Create, FileAccess.Write, FileShare.None);
     79             using (stream)
     80             {
     81                 formatter.Serialize(stream, p);
     82             }
     83             Console.WriteLine("序列化完成!");
     84             Console.ReadKey();
     85             Console.WriteLine("按任意键继续反序列化!");
     86             Console.ReadKey();
     87         }
     88         //BinaryFormatter方式反序列化
     89         private static void Deserializable()
     90         {
     91             Person<Work> p;
     92             IFormatter formatter = new BinaryFormatter();
     93             Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Open, FileAccess.Read, FileShare.None);
     94             using (stream)
     95             {
     96                 p = (Person<Work>)formatter.Deserialize(stream);
     97             }
     98             if (p.W == null)
     99             {
    100                 Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age );
    101             }
    102             else
    103             {
    104                 Console.WriteLine("Person类的Work属性未被实例化!");
    105             }
    106             
    107         }
    108 
    109 
    110  //BinaryFormatter方式序列化
    111         private static void Serializable(Person<Work> p)
    112         {
    113             IFormatter formatter = new BinaryFormatter();
    114             //创建文件流
    115             Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Create, FileAccess.Write, FileShare.None);
    116             using (stream)
    117             {
    118                 formatter.Serialize(stream, p);
    119             }
    120             Console.WriteLine("序列化完成!");
    121             Console.ReadKey();
    122             Console.WriteLine("按任意键继续反序列化!");
    123             Console.ReadKey();
    124         }
    125         //BinaryFormatter方式反序列化
    126         private static void Deserializable()
    127         {
    128             Person<Work> p;
    129             IFormatter formatter = new BinaryFormatter();
    130             Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Open, FileAccess.Read, FileShare.None);
    131             using (stream)
    132             {
    133                 p = (Person<Work>)formatter.Deserialize(stream);
    134             }
    135             if (p.W == null)
    136             {
    137                 Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age );
    138             }
    139             else
    140             {
    141                 Console.WriteLine("Person类的Work属性未被实例化!");
    142             }
    143             
    144         }
    145 
    146 在Main函数中调用如下
    147 
    148  static void Main(string[] args)
    149         {
    150             Person<Work> p = new Person<Work>()
    151             {
    152                 Name = "Olive",
    153                 Sex = "female",
    154                 Age = 22,
    155                 W = new Work()
    156                 {
    157                     WorkName = "Student"
    158                 }
    159             };
    160 
    161             Serializable(p);      //BinaryFormatter序列化,将对象以二进制流的方式写入本地文件
    162             Deserializable();     //BinaryFormatter反序列化 ,从本地文件读取二进制流,反序列化为对象
    163 
    164 }
    165 
    166 执行完之后效果如下:
    167 
    168 1、在D盘产生一个Person.bin文件,保存的就是Person对象的属性,
    169 
    170 2、反序列化后,可以重新得到对象
    171 
    172 
    173 
    174 二、SoapFormatter
    175 
    176 要序列化成SOAP就要先用引用System.Runtime.Serialization.Formatters.Soap命名空间中的SoapFormatter类。
    177 
    178 SoapFormatter是一个Soap的格式器
    179 
    180 具体的代码如下:(还是引用开始的Person类)
    181 
    182    //SoapFormatter方式序列化
    183         private static void SoapSerializable(Person p)
    184         {
    185             IFormatter formatter = new SoapFormatter();
    186             Stream stream=new FileStream(@"D:\Person.xml",FileMode.Create,FileAccess.Write,FileShare.None);
    187             using(stream)
    188             {
    189             formatter.Serialize(stream,p);
    190             }
    191             Console.WriteLine("SoapSerializable序列化完毕!");
    192         }
    193         //SoapFormatter反序列化
    194         private static void DesoapSerializable()
    195         {
    196             Person  p;
    197             IFormatter formatter = new SoapFormatter();
    198             Stream stream = new FileStream(@"D:\Person.xml", FileMode.Open, FileAccess.Read, FileShare.None);
    199             using (stream)
    200             {
    201                 p = (Person )formatter.Deserialize(stream);
    202             }
    203             Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
    204             Console.WriteLine("SoapSerializable反序列化完毕!");
    205         }
    206 
    207 主函数
    208 
    209    static void Main(string[] args)
    210         {
    211             Person  p = new Person()
    212             {
    213                 Name = "Olive",
    214                 Sex = "female",
    215                 Age = 22,
    216                 W = new Work()
    217                 {
    218                     WorkName = "Student"
    219                 }
    220             };
    221 
    222       SoapSerializable(p); //SoapFormatter序列化,(但是不支持泛型的序列化 )将对象序列化为xml格式的字符串,存入本地.xml文件
    223             DesoapSerializable(); //SoapFormatter反序列化
    224 
    225 }
    226 
    227 执行完之后效果如下:
    228 
    229 1、在D盘产生一个Person.XML文件,保存的就是Person对象的属性,
    230 
    231 2、反序列化后,可以重新得到对象
    232 
    233 
    234 
    235 三、XmlSerializer
    236 
    237 首先需要引入命名空间:System.Xml.Serialization
    238 
    239 主要代码如下:
    240 
    241 //XMLSerializable序列化
    242         private static void XMLSerializable(Person<Work> p)
    243         {
    244             XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
    245             Stream stream = new FileStream(@"D:\XMLPerson.xml", FileMode.Create, FileAccess.Write, FileShare.None);
    246             using (stream)
    247             {
    248                 xmlSerializer.Serialize(stream, p);
    249             }
    250             Console.WriteLine("XMLSerializable序列化完毕!");
    251             Console.WriteLine("按任意键继续反序列化!");
    252             Console.ReadKey();
    253         }
    254         //XMLSerializable反序列化
    255         private static void DeXMLSerializable()
    256         {
    257             Person<Work> p;
    258             XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
    259             Stream stream = new FileStream(@"D:\XMLPerson.xml", FileMode.Open, FileAccess.Read, FileShare.None);
    260             using (stream)
    261             {
    262                 p = (Person<Work>)xmlSerializer.Deserialize(stream);
    263             }
    264             if (p != null)
    265             {
    266                 Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
    267                 Console.WriteLine("XMLSerializable反序列化成功!");
    268 
    269             }
    270             else
    271                 Console.WriteLine("XMLSerializable反序列化失败!");
    272         }
    273 
    274 
    275 主函数调用如下:
    276 
    277 static void Main(string[] args)
    278         {
    279             Person<Work> p = new Person<Work>()
    280             {
    281                 Name = "Olive",
    282                 Sex = "female",
    283                 Age = 22,
    284                 W = new Work()
    285                 {
    286                     WorkName = "Student"
    287                 }
    288             };
    289 
    290     XMLSerializable(p);   //XMLSerializable序列化 ,将对象序列化为XML格式的字符串
    291             DeXMLSerializable();  // XMLSerializable序列化
    292 
    293 }
    294 
    295 执行后效果如下:
    296 
    297 1、在D盘产生一个XMLPerson.XML文件,保存的就是Person对象的属性,
    298 
    299 2、反序列化后,可以重新得到对象
    300 
    301 
    302 
    303 
    304 这里的跟节点之所是Hello而不是Person是因为在Person类中,将Person的类的跟节点标记为 
    305 
    306 [XmlRoot("Hello")]
    307     public  class Person<T>{}
    308 
    309 同时Work的节点名为W也是这个缘故
    310 
    311   [XmlAttribute("WorkName")]
    312         public string WorkName
    313         {
    314             get;
    315             set;
    316         }
    317 
    318 四、DataContractJsonSerializer(将对象序列化为Json格式的字符串)
    319 
    320 在使用前需要添加引用:System.ServiceModel.Web 和 System.Runtime.Serialization,
    321 
    322 然后使用
    323 
    324 using System.Runtime.Serialization.Json;ITPUB个人空间3htH4O+A.sQ!n
    325 using System.Runtime.Serialization;
    326 
    327 具体代码如下:
    328 
    329 
    330     //SerializableJson 将对象序列化为Json格式字符串
    331         private static string SerializableJson(Person<Work> p)
    332         {
    333             DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Person<Work>));
    334             using (MemoryStream memory = new MemoryStream())
    335             {
    336                 serializer.WriteObject(memory, p);
    337                 result = UTF8Encoding.Default.GetString(memory.ToArray());
    338                 Console.WriteLine(result);
    339             }
    340             Console.WriteLine("SerializableJson序列化完毕!");
    341             return result;
    342         }
    343         //SerializableJson 将Json格式的字符串序列化为对象
    344         private static void DeSerializableJson(string jsonString)
    345         {
    346             Person<Work> p;
    347             var serializer = new DataContractJsonSerializer(typeof(Person<Work>));
    348             using (MemoryStream memory = new MemoryStream(UTF8Encoding.Default.GetBytes(jsonString)))
    349             {
    350                 p = (Person<Work>)serializer.ReadObject(memory);
    351             }
    352             Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
    353             Console.WriteLine("Json序列化完毕了!");
    354             Console.WriteLine("按任意键继续");
    355             Console.ReadKey();
    356         }
    357 
    358 主函数调用
    359 
    360 static void Main(string[] args)
    361         {
    362             Person<Work> p = new Person<Work>()
    363             {
    364                 Name = "Olive",
    365                 Sex = "female",
    366                 Age = 22,
    367                 W = new Work()
    368                 {
    369                     WorkName = "Student"
    370                 }
    371             };
    372 
    373 执行结果如下:
    374 
    375 
    376 
    377 
    378 五、DataContactSerializer(可以将对象序列化为Json格式的字符串和XML格式的字符串,为Json格式时,需要在将要序列化的类属性上添加[DataMember]特性,
    379 
    380 为XML格式时,需要在将要序列化的类属性上添加[XmlAttribute("属性名")]特性,这样就会根据所添加的特性的不同而生成不同格式的字符串
    381 
    382 首先需要添加引用:
    383 
    384 using System.ServiceModel;
    385 
    386 具体代码如下:(生成JSON格式的字符串)
    387 
    388  private static string SerializerDataContract(Person<Work> p)
    389         {
    390             DataContractSerializer dataSerializer = new DataContractSerializer(typeof(Person<Work>));
    391             using (MemoryStream memory = new MemoryStream())
    392             {
    393                 dataSerializer.WriteObject(memory, p);
    394                 result = UTF8Encoding.Default.GetString(memory.ToArray());
    395                 Console.WriteLine(result);
    396                 Console.WriteLine("DataContractSerializer序列化完毕!");
    397             }
    398             return result;
    399 
    400         }
    401         private static void DeSerializerDataContract(string result)
    402         {
    403             Person<Work> p;
    404             DataContractSerializer dataSerializer = new DataContractSerializer(typeof(Person<Work>));
    405             using (MemoryStream memory = new MemoryStream(UTF8Encoding.Default.GetBytes(result)))
    406             {
    407                 p = (Person<Work>)dataSerializer.ReadObject(memory);
    408                 Console.WriteLine(p.Name + ":::" + p.Sex + ":::" + p.Age);
    409             }
    410         }
    411 
    412 主函数调用:
    413 
    414         static void Main(string[] args)
    415         {
    416             Person<Work> p = new Person<Work>()
    417             {
    418                 Name = "Olive",
    419                 Sex = "female",
    420                 Age = 22,
    421                 W = new Work()
    422                 {
    423                     WorkName = "Student"
    424                 }
    425             };
    426  SerializerDataContract(p);
    427             DeSerializerDataContract(result);
    428 
    429 }
    430 
    431 执行结果如下:
    432 
    433 
    434 
    435 六、将对象序列化为字符串、或者字节数组
    436 
    437 先要引用命名空间
    438 
    439 using System.Runtime.Serialization;
    440 using System.Runtime.Serialization.Formatters;
    441 using System.Runtime.Serialization.Formatters.Soap;
    442 using System.Runtime.Serialization.Formatters.Binary;
    443 
    444 
    445 using system.Runtime.
    446 
    447 主要代码:
    448 
    449        //SerializableString将对象序列化为字符串
    450         private static string SerializableString(Person<Work> p)
    451         {
    452 
    453             XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
    454             using (MemoryStream memoryStream = new MemoryStream())
    455             {
    456                 xmlSerializer.Serialize(memoryStream, p);
    457                 result = UTF8Encoding.Default.GetString(memoryStream.ToArray());
    458                 Console.WriteLine(result);
    459                 return result;
    460 
    461             }
    462         }
    463         //将字符串反序列化为对象
    464         public static void DeSerializableString(string result, Person<Work> p)
    465         {
    466             XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
    467             using (StringReader stringReader = new StringReader(result))
    468             {
    469                 p = (Person<Work>)xmlSerializer.Deserialize(stringReader);
    470             }
    471             Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
    472             Console.WriteLine("反序列化完毕!");
    473 
    474         }
    475         private static byte[] buffer;
    476         //将对象序列化为字节数组
    477         private static byte[] SerializableObjcet(Person<Work> p)
    478         {
    479 
    480             IFormatter formatter = new BinaryFormatter();
    481             MemoryStream stream = new MemoryStream();
    482             buffer = new byte[stream.Length];
    483             using (stream)
    484             {
    485                 formatter.Serialize(stream, p);
    486                 stream.Position = 0;
    487                 stream.Read(buffer, 0, buffer.Length);
    488             }
    489 
    490             Console.WriteLine("Serialization字节数组转换成功!");
    491             return buffer;
    492         }
    493         //将字节数组转化为对象
    494         private static void DeSerializableObject(byte[] bytes)
    495         {
    496 
    497             if (buffer != null)
    498             {
    499                 Person<Work> p;
    500                 IFormatter formatter = new BinaryFormatter();
    501                 MemoryStream stream = new MemoryStream(bytes);
    502                 using (stream)
    503                 {
    504                     p = (Person<Work>)formatter.Deserialize(stream);
    505                 }
    506                 Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
    507                 Console.WriteLine("字节数组反序列化成功!");
    508             }
    509             else
    510             {
    511                 Console.WriteLine("字节数组为空!");
    512             }
    513         }
    514 
    515 执行结果如下:
    516 
    517 
    518 
    519 至此,基本上已经介绍了常用的序列化的方法,希望能对大家有一定的帮助,同时也算是我自己的学习总结吧!
  • 相关阅读:
    [hackerrank]The Love-Letter Mystery
    *[hackerrank]Algorithmic Crush
    [hackerrank]Palindrome Index
    [hackerrank]Closest Number
    [hackerrank]Even Odd Query
    *[hackerrank]Consecutive Subsequences
    Permutation Sequence(超时,排列问题)
    Set Matrix Zeroes
    python requests的安装与简单运用(转)
    字符串指针数组,指向指针的指针
  • 原文地址:https://www.cnblogs.com/Olive116/p/Serialization.html
Copyright © 2020-2023  润新知