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、反序列化后,可以重新得到对象

Serialization全解析_第1张图片

二、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、反序列化后,可以重新得到对象

Serialization全解析_第2张图片Serialization全解析_第3张图片

这里的跟节点之所是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"
                 }
             };

结果如下:


Serialization全解析_第4张图片  五、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("字节数组为空!");
            }
         }
执行结果如下:

Serialization全解析_第5张图片

至此,基本上已经介绍了常用的序列化的方法,希望能对大家有一定的帮助,同时也算是我自己的学习总结吧!

你可能感兴趣的:(json,String,Stream,serialization,buffer,SOAP)