当前位置: 首页 > web >正文

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("字节数组为空!");
            }
         }
执行结果如下:


转自:http://blog.csdn.net/xuemoyao/article/details/8028429

http://www.xdnf.cn/news/11431.html

相关文章:

  • 无线网络领域国际会议/期刊排名
  • CSS教程:div垂直居中的N种方法
  • SLIC超像素分割详解(一)(二)(三)
  • verilog之testbench的写法
  • 免费标准下载网站
  • 为什么需要协调能力?如何提高协调能力?
  • ENet特性简介
  • SQL Server 数据库
  • 轻松搞定!png格式图片怎么弄?详细方法一网打尽
  • 电脑提示由于找不到xinput1_3.dll,无法继续执行代码有什么好的解决办法
  • Python批量下载ts视频文件,并用ffmpeg合并
  • AI人工智能原理与Python实战:Python人工智能行业应用 2
  • 低级格式化软件测试,低级格式化,几款优秀的低级格式化工具对比制作步骤
  • 五款优秀的FTP工具
  • Java6 JDK的安装
  • 什么是Web 2.0
  • Turbo C 2.0使用教程(非常详细)从零基础入门到精通,看完这一篇就够了
  • BeanUtils与MapStruct
  • latex希腊字母一览表
  • 方差计算算法-在线更新算法
  • EtherCAT运动控制卡的SCARA等机器人指令的应用
  • 最大似然估计与参数估计:深入理解关系
  • 在家刷剧的一般方式
  • 必须知道的技术博客网站100条
  • CSS基础知识
  • 元素尺寸总结(offsetWidth,clientWidth,scrollWidth)
  • Matlab----下载和安装教程
  • MAXDOS网刻教程~~(虚拟机与物理机 / 两台或者多台电脑之间)
  • Android 开发简介
  • Android教程-从零开始一步一步接入SDK