• Serialization全解析


    Serialization即序列化,序列化是可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本。
     
     Remoting和Web Service就是序列化的典型的应用,通过序列化将一个对象从一个应用程序域,发送到另一个应用程序域。
     
     序列化类默认的情况下是要求他的所有的成员都是要可序列化的(除事件、委托、显式定义不可序列化),对于不想被序列化的成员要声明不可序列化把它加上 [NonSerialized]属性告诉.NET这个类不要被序列化,这样在序列化的时候就不会保存对象的状态。
     
     下面就将常用的几种序列化方式一一实现出来给大家看一下!
     
     首先需要新建一个被实例化的类:Person.cs
     
     namespace SerializationTest
     {
         [Serializable]//此属性标记为该类可以实例化
         [XmlRoot("Hello")]//标记为XML文档的根节点名字
         public  class Person<T>
         {
            [XmlAttribute("Name")]/标记为XML文档属性名
           public string Name
            {
                get;
                set;
            }
           [XmlAttribute("Sex")]
           public string Sex
           {
               get;
               set;
           }
           [XmlAttribute("Age")]
           public int Age
           {
               get;
               set;
           }
           [NonSerialized]//此属性标记为不可序列化
           Work w;
           public Work W
           {
               get
               {
                   return w;
               }  
               set
               {
                   w = value;
               }
           }
         }
          
         public class Work
         {
               [XmlAttribute("WorkName")]
             public string WorkName
             {
                 get;
                 set;
             }
         }
     
     
     下面开始介绍常使用的几种序列化的方法
     
     一、BinaryFormatter
     
     在使用之前需要先引入命名空间:
     
     using System.Runtime.Serialization;
     using System.Runtime.Serialization.Formatters;
     using System.Runtime.Serialization.Formatters.Binary;
     
     具体的实现方法如下:
     
      //BinaryFormatter方式序列化
             private static void Serializable(Person<Work> p)
             {
                 IFormatter formatter = new BinaryFormatter();
                 //创建文件流
                 Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Create, FileAccess.Write, FileShare.None);
                 using (stream)
                 {
                     formatter.Serialize(stream, p);
                 }
                 Console.WriteLine("序列化完成!");
                 Console.ReadKey();
                 Console.WriteLine("按任意键继续反序列化!");
                 Console.ReadKey();
             }
             //BinaryFormatter方式反序列化
             private static void Deserializable()
             {
                 Person<Work> p;
                 IFormatter formatter = new BinaryFormatter();
                 Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Open, FileAccess.Read, FileShare.None);
                 using (stream)
                 {
                     p = (Person<Work>)formatter.Deserialize(stream);
                 }
                 if (p.W == null)
                 {
                     Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age );
                 }
                 else
                 {
                     Console.WriteLine("Person类的Work属性未被实例化!");
                 }
                
             }
     
     
      //BinaryFormatter方式序列化
             private static void Serializable(Person<Work> p)
             {
                 IFormatter formatter = new BinaryFormatter();
                 //创建文件流
                 Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Create, FileAccess.Write, FileShare.None);
                 using (stream)
                 {
                     formatter.Serialize(stream, p);
                 }
                 Console.WriteLine("序列化完成!");
                 Console.ReadKey();
                 Console.WriteLine("按任意键继续反序列化!");
                 Console.ReadKey();
             }
             //BinaryFormatter方式反序列化
             private static void Deserializable()
             {
                 Person<Work> p;
                 IFormatter formatter = new BinaryFormatter();
                 Stream stream = new FileStream(@"D:\Persons.bin", FileMode.Open, FileAccess.Read, FileShare.None);
                 using (stream)
                 {
                     p = (Person<Work>)formatter.Deserialize(stream);
                 }
                 if (p.W == null)
                 {
                     Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age );
                 }
                 else
                 {
                     Console.WriteLine("Person类的Work属性未被实例化!");
                 }
                
             }
     
     在Main函数中调用如下
     
      static void Main(string[] args)
             {
                 Person<Work> p = new Person<Work>()
                 {
                     Name = "Olive",
                     Sex = "female",
                     Age = 22,
                     W = new Work()
                     {
                         WorkName = "Student"
                     }
                 };
     
                 Serializable(p);      //BinaryFormatter序列化,将对象以二进制流的方式写入本地文件
                 Deserializable();     //BinaryFormatter反序列化 ,从本地文件读取二进制流,反序列化为对象
     
     }
     
     执行完之后效果如下:
     
     1、在D盘产生一个Person.bin文件,保存的就是Person对象的属性,
     
     2、反序列化后,可以重新得到对象
     
     
     
     二、SoapFormatter
     
     要序列化成SOAP就要先用引用System.Runtime.Serialization.Formatters.Soap命名空间中的SoapFormatter类。
     
     SoapFormatter是一个Soap的格式器
     
     具体的代码如下:(还是引用开始的Person类)
     
        //SoapFormatter方式序列化
             private static void SoapSerializable(Person p)
             {
                 IFormatter formatter = new SoapFormatter();
                 Stream stream=new FileStream(@"D:\Person.xml",FileMode.Create,FileAccess.Write,FileShare.None);
                 using(stream)
                 {
                 formatter.Serialize(stream,p);
                 }
                 Console.WriteLine("SoapSerializable序列化完毕!");
             }
             //SoapFormatter反序列化
             private static void DesoapSerializable()
             {
                 Person  p;
                 IFormatter formatter = new SoapFormatter();
                 Stream stream = new FileStream(@"D:\Person.xml", FileMode.Open, FileAccess.Read, FileShare.None);
                 using (stream)
                 {
                     p = (Person )formatter.Deserialize(stream);
                 }
                 Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
                 Console.WriteLine("SoapSerializable反序列化完毕!");
             }
     
     主函数
     
        static void Main(string[] args)
             {
                 Person  p = new Person()
                 {
                     Name = "Olive",
                     Sex = "female",
                     Age = 22,
                     W = new Work()
                     {
                         WorkName = "Student"
                     }
                 };
     
           SoapSerializable(p); //SoapFormatter序列化,(但是不支持泛型的序列化 )将对象序列化为xml格式的字符串,存入本地.xml文件
                 DesoapSerializable(); //SoapFormatter反序列化
     
     }
     
     执行完之后效果如下:
     
     1、在D盘产生一个Person.XML文件,保存的就是Person对象的属性,
     
     2、反序列化后,可以重新得到对象
     
     
     
     三、XmlSerializer
     
     首先需要引入命名空间:System.Xml.Serialization
     
     主要代码如下:
     
     //XMLSerializable序列化
             private static void XMLSerializable(Person<Work> p)
             {
                 XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
                 Stream stream = new FileStream(@"D:\XMLPerson.xml", FileMode.Create, FileAccess.Write, FileShare.None);
                 using (stream)
                 {
                     xmlSerializer.Serialize(stream, p);
                 }
                 Console.WriteLine("XMLSerializable序列化完毕!");
                 Console.WriteLine("按任意键继续反序列化!");
                 Console.ReadKey();
             }
             //XMLSerializable反序列化
             private static void DeXMLSerializable()
             {
                 Person<Work> p;
                 XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
                 Stream stream = new FileStream(@"D:\XMLPerson.xml", FileMode.Open, FileAccess.Read, FileShare.None);
                 using (stream)
                 {
                     p = (Person<Work>)xmlSerializer.Deserialize(stream);
                 }
                 if (p != null)
                 {
                     Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
                     Console.WriteLine("XMLSerializable反序列化成功!");
     
                 }
                 else
                     Console.WriteLine("XMLSerializable反序列化失败!");
             }
     
     
     主函数调用如下:
     
     static void Main(string[] args)
             {
                 Person<Work> p = new Person<Work>()
                 {
                     Name = "Olive",
                     Sex = "female",
                     Age = 22,
                     W = new Work()
                     {
                         WorkName = "Student"
                     }
                 };
     
         XMLSerializable(p);   //XMLSerializable序列化 ,将对象序列化为XML格式的字符串
                 DeXMLSerializable();  // XMLSerializable序列化
     
     }
     
     执行后效果如下:
     
     1、在D盘产生一个XMLPerson.XML文件,保存的就是Person对象的属性,
     
     2、反序列化后,可以重新得到对象
     
     
     
     
     这里的跟节点之所是Hello而不是Person是因为在Person类中,将Person的类的跟节点标记为
     
     [XmlRoot("Hello")]
         public  class Person<T>{}
     
     同时Work的节点名为W也是这个缘故
     
       [XmlAttribute("WorkName")]
             public string WorkName
             {
                 get;
                 set;
             }
     
     四、DataContractJsonSerializer(将对象序列化为Json格式的字符串)
     
     在使用前需要添加引用:System.ServiceModel.Web 和 System.Runtime.Serialization,
     
     然后使用
     
     using System.Runtime.Serialization.Json;ITPUB个人空间3htH4O+A.sQ!n
     using System.Runtime.Serialization;
     
     具体代码如下:
     
     
         //SerializableJson 将对象序列化为Json格式字符串
             private static string SerializableJson(Person<Work> p)
             {
                 DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Person<Work>));
                 using (MemoryStream memory = new MemoryStream())
                 {
                     serializer.WriteObject(memory, p);
                     result = UTF8Encoding.Default.GetString(memory.ToArray());
                     Console.WriteLine(result);
                 }
                 Console.WriteLine("SerializableJson序列化完毕!");
                 return result;
             }
             //SerializableJson 将Json格式的字符串序列化为对象
             private static void DeSerializableJson(string jsonString)
             {
                 Person<Work> p;
                 var serializer = new DataContractJsonSerializer(typeof(Person<Work>));
                 using (MemoryStream memory = new MemoryStream(UTF8Encoding.Default.GetBytes(jsonString)))
                 {
                     p = (Person<Work>)serializer.ReadObject(memory);
                 }
                 Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
                 Console.WriteLine("Json序列化完毕了!");
                 Console.WriteLine("按任意键继续");
                 Console.ReadKey();
             }
     
     主函数调用
     
     static void Main(string[] args)
             {
                 Person<Work> p = new Person<Work>()
                 {
                     Name = "Olive",
                     Sex = "female",
                     Age = 22,
                     W = new Work()
                     {
                         WorkName = "Student"
                     }
                 };
     
     执行结果如下:
     
     
     
     
     五、DataContactSerializer(可以将对象序列化为Json格式的字符串和XML格式的字符串,为Json格式时,需要在将要序列化的类属性上添加[DataMember]特性,
     
     为XML格式时,需要在将要序列化的类属性上添加[XmlAttribute("属性名")]特性,这样就会根据所添加的特性的不同而生成不同格式的字符串
     
     首先需要添加引用:
     
     using System.ServiceModel;
     
     具体代码如下:(生成JSON格式的字符串)
     
      private static string SerializerDataContract(Person<Work> p)
             {
                 DataContractSerializer dataSerializer = new DataContractSerializer(typeof(Person<Work>));
                 using (MemoryStream memory = new MemoryStream())
                 {
                     dataSerializer.WriteObject(memory, p);
                     result = UTF8Encoding.Default.GetString(memory.ToArray());
                     Console.WriteLine(result);
                     Console.WriteLine("DataContractSerializer序列化完毕!");
                 }
                 return result;
     
             }
             private static void DeSerializerDataContract(string result)
             {
                 Person<Work> p;
                 DataContractSerializer dataSerializer = new DataContractSerializer(typeof(Person<Work>));
                 using (MemoryStream memory = new MemoryStream(UTF8Encoding.Default.GetBytes(result)))
                 {
                     p = (Person<Work>)dataSerializer.ReadObject(memory);
                     Console.WriteLine(p.Name + ":::" + p.Sex + ":::" + p.Age);
                 }
             }
     
     主函数调用:
     
             static void Main(string[] args)
             {
                 Person<Work> p = new Person<Work>()
                 {
                     Name = "Olive",
                     Sex = "female",
                     Age = 22,
                     W = new Work()
                     {
                         WorkName = "Student"
                     }
                 };
      SerializerDataContract(p);
                 DeSerializerDataContract(result);
     
     }
     
     执行结果如下:
     
     
     
     六、将对象序列化为字符串、或者字节数组
     
     先要引用命名空间
     
     using System.Runtime.Serialization;
     using System.Runtime.Serialization.Formatters;
     using System.Runtime.Serialization.Formatters.Soap;
     using System.Runtime.Serialization.Formatters.Binary;
     
     
     using system.Runtime.
     
     主要代码:
     
            //SerializableString将对象序列化为字符串
             private static string SerializableString(Person<Work> p)
             {
     
                 XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
                 using (MemoryStream memoryStream = new MemoryStream())
                 {
                     xmlSerializer.Serialize(memoryStream, p);
                     result = UTF8Encoding.Default.GetString(memoryStream.ToArray());
                     Console.WriteLine(result);
                     return result;
     
                 }
             }
             //将字符串反序列化为对象
             public static void DeSerializableString(string result, Person<Work> p)
             {
                 XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person<Work>));
                 using (StringReader stringReader = new StringReader(result))
                 {
                     p = (Person<Work>)xmlSerializer.Deserialize(stringReader);
                 }
                 Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
                 Console.WriteLine("反序列化完毕!");
     
             }
             private static byte[] buffer;
             //将对象序列化为字节数组
             private static byte[] SerializableObjcet(Person<Work> p)
             {
     
                 IFormatter formatter = new BinaryFormatter();
                 MemoryStream stream = new MemoryStream();
                 buffer = new byte[stream.Length];
                 using (stream)
                 {
                     formatter.Serialize(stream, p);
                     stream.Position = 0;
                     stream.Read(buffer, 0, buffer.Length);
                 }
     
                 Console.WriteLine("Serialization字节数组转换成功!");
                 return buffer;
             }
             //将字节数组转化为对象
             private static void DeSerializableObject(byte[] bytes)
             {
     
                 if (buffer != null)
                 {
                     Person<Work> p;
                     IFormatter formatter = new BinaryFormatter();
                     MemoryStream stream = new MemoryStream(bytes);
                     using (stream)
                     {
                         p = (Person<Work>)formatter.Deserialize(stream);
                     }
                     Console.WriteLine(p.Name + "::" + p.Sex + "::" + p.Age);
                     Console.WriteLine("字节数组反序列化成功!");
                 }
                 else
                 {
                     Console.WriteLine("字节数组为空!");
                 }
             }
     
     执行结果如下:
     
     
     

  • 相关阅读:
    maven第三章 maven使用入门
    各个软件产生的原因
    maven的pom.xml深入理解
    批量同步订单信息(包括状态)到订单中心心得
    数据库连接超时和go away、如何检测数据库的最大连接数
    记录错误日志的技巧
    架构思想总结同步和事务的具体应用
    业务逻辑复杂性处理
    日志系统总结
    php捕获异常的处理
  • 原文地址:https://www.cnblogs.com/amylis_chen/p/2707338.html
Copyright © 2020-2023  润新知