序列化浅谈

来源:互联网 发布:什么样的大数据才有用 编辑:程序博客网 时间:2024/06/09 15:43

1:为什么需要序列化

     序列化是将对象转换为字节流以将其保存在内存、数据库或文件中的过程。其主要目的是保存对象的状态,以便可以在需要时重新创建对象。作用就是转换网络传输的语言数据(二进制,XML,SQAP)。相反的过程称为反序列化。

     此图显示序列化的整个过程。

图:序列化

     对象被序列化为流。流传递的不仅是数据,还包括有关对象类型的信息,如对象的版本、区域性和程序集名称。通过该流,可以将对象存储在数据库、文件或内存中。

2:序列化的几种格式

     序列化对象的时候,有三种格式:二进制、XML、SOAP。(BinaryFormatter、XmlSerializer、SoapFormatter)

     二进制序列化使用二进制编码来生成精简的序列化,以用于存储或基于套接字的网络流等。二进制格式对于大多数 Windows 应用程序均适用。

     XML 序列化将对象的公共字段和属性或者方法的参数及返回值序列化为符合特定 XML 架构定义语言 (XSD) 文档的 XML 流。XML 序列化会生成具有转换为 XML 的公共属性和字段的强类型类。

     XML 序列化还可用于将对象序列化为符合 SOAP 规范的 XML 流。对于 Web 应用程序或 Web 服务,SOAP 格式对象可以用于你像使用其它语言环境编写的应用程序接口。

 

2:几种序列化的小例子

 

 首先,先给一个实体类,记得要写 [Serializable]  标记为可序列化;注意如果没有实现 ISerializable  接口的类需要实现 ISerializable  接口

  注意:如果不希望哪个属性序列化 在这个属性头上加上[NonSerialized]

[c-sharp] view plaincopyprint?
  1.    [Serializable()]   
  2.    class Employee: ISerializable  
  3.     {  
  4.  //可使用[NonSerialized]或[XmlIgnore]标识该元素在序列化时跳过  
  5.        public int EmpId;   
  6.        //我不希望EmpName字段序列化
  7.        [NonSerialized]
  8.        public String EmpName;  
  9.        public Employee(){  
  10.            EmpId = 0;  
  11.            EmpName = "alex";  
  12.        }  
  13. }  


.net框架支持多种序列化方式:BinaryFormatter、SoapFormatter、XmlSerializer。BinaryFormatter序列化时将对象格式化为简单的二进制数据流及附加的类型信息;SoapFormatter、XmlSerializer将对象格式化为XML格式,但XmlSerializer比Soap要简化很多,去掉了Soap特有的额外信息。

如果某个类需要序列化,该类需要标记为[Serializable]。而类中某个元素不想被序列化,可使用[NonSerialized]或[XmlIgnore]来标记. 

  1. 使用BinaryFormatter进行序列化
     
    [c-sharp] view plaincopyprint?
    1. public void BinarySerialize(){  
    2.         Employee emp = new Employee();  
    3.         FileStream fileStream = new FileStream("c://temp.dat", FileMode.Create);  
    4.         BinaryFormatter b = new BinaryFormatter();  
    5.         b.Serialize(fileStream, emp );  
    6.         fileStream.Close();  
    7.     }  
    8. public void BinaryDeSerialize(){  
    9.         Employee emp = new Employee ();  
    10.         FileStream fileStream = new FileStream("c://temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);  
    11.         BinaryFormatter b = new BinaryFormatter();  
    12.         emp = (Employee)b.Deserialize(fileStream) ;  
    13.         fileStream.Close();  
    14.     }  
  2. 使用SoapFormatter进行序列化
     与Binary类似,序列化后得到的是一个XML文件
     
    [c-sharp] view plaincopyprint?
    1. public void SoapSerialize(){  
    2.         Employee emp = new Employee();  
    3.         FileStream fileStream = new FileStream("c://temp.xml", FileMode.Create);  
    4.         SoapFormatterb = new SoapFormatter();  
    5.         b.Serialize(fileStream, emp );  
    6.         fileStream.Close();  
    7.     }  
    8. public void SoapDeSerialize(){  
    9.         Employee emp = new Employee ();  
    10.         FileStream fileStream = new FileStream("c://temp.xml", FileMode.Open, FileAccess.Read, FileShare.Read);  
    11.        SoapFormatterb = new SoapFormatter();  
    12.        emp = (Employee)b.Deserialize(fileStream) ;  
    13.        fileStream.Close();  
    14.     }  
  3. 使用XmlSerializer进行序列化

 与Binary类似,没有soap的额外信息

[c-sharp] view plaincopyprint?
  1. public void XmlSerialize(){  
  2.         Employee emp = new Employee();  
  3.         FileStream fileStream = new FileStream("c://temp.xml", FileMode.Create);  
  4.         XmlSerializer xs = new XmlSerializer (typeof(Employee));  
  5.         xs.Serialize(fileStream, emp );  
  6.         fileStream.Close();  
  7.     }  
  8. public void XmlDeSerialize(){  
  9.         Employee emp = new Employee ();  
  10.         FileStream fileStream = new FileStream("c://temp.xml", FileMode.Open, FileAccess.Read, FileShare.Read);  
  11.        XmlSerializer xs = new XmlSerializer (typeof(Employee));  
  12.        emp = (Employee)xs.Deserialize(fileStream) ;  
  13.        fileStream.Close();  
  14.     }  

 

 自定义的序列化形式:

Employee 实例的对象在序列化是将相关成员写入到字节流中。如果需要自定义数据流的组织方式,可以通过在类中实现ISeriable接口来自定义序列化行为。该接口有一个方法GetObjectData,用于将类对象的数据填充进SerializationInfo对象。在序列化时,指定的格式化器将构造SerializationInfo对象,然后在串行化时调用GetObjetcDAta;在反序列化时,格式化器化调用一个特定原型的构造器从SerializationInfo对象中还原出Employee 实例的对象。代码见下:

[c-sharp] view plaincopyprint?
  1. [Serializable()]   
  2.    class Employee: ISerializable  
  3.     {  
  4.        public int EmpId;  
  5.        public String EmpName;  
  6.        public Employee(){  
  7.            EmpId = 0;  
  8.            EmpName = "alex";  
  9.        }  
  10.        //反序列化时调用的重构函数   
  11.        public Employee(SerializationInfo  info, StreamingContext context){  
  12.            this.EmpId = info.GetInt32("empid");  
  13.            this.EmpName = info.GetString("empname");  
  14.        }  
  15.        //序列化时重写的函数,将数据填充到SerializationInfo  
  16.        public void GetObjectData(SerializationInfo info, StreamingContext context) {  
  17.            info.AddValue("empid", EmpId);  
  18.            info.AddValue("empname", EmpName);  
  19.        }  
  20.     }  

 

 

--------------------------------------------------分割线------------------------------------------------------------ 

貌似XML序列化复杂很多  :找到一篇文章,对我对大家相信都有一定的帮助

 

首先创建一个class

   [Serializable]
  public class SerializationClass
    {
        public string Name
        {
            get;
            set;
        }

        public int Age
        {
            get;
            set;
        }
    }

 

上面的红色字体就是声明序列化    如果不希望哪个属性序列化 在这个属性头上加上[NonSerialized]

       static void Main(string[] args)
        {
            SerializationClass serialization = new SerializationClass();
            serialization.Name = "mldark";
            serialization.Age = 24;
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binary = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            //序列化
            using (System.IO.FileStream stream = new FileStream("user.dat",FileMode.Create  , FileAccess.Write , FileShare.None))
            {

                binary.Serialize(stream, serialization);
           
            }
            //反序列化
            using (FileStream fileread = new FileStream("user.dat", FileMode.Open))
            {
                serialization = binary.Deserialize(fileread)as SerializationClass ;

            }

 


          
        }

上面是Binary序列化   那么xml和Soap序列化一样的方法

Soap序列化在 System.Runtime.Serialization.Formatters.Soap.SoapFormatter

xml序列化在 System.Xml.Serialization.XmlSerializer  

其中最复杂就是xml序列化 因为它可以更多操作

如果熟悉xml方面 对这个操作比较容易多

首先创建一个类型

    [Serializable,XmlRoot]
  public class SerializationClass
    {  
     
        [XmlElement]
        public string Name
        {
            get;
            set;
        }
       [XmlAttribute]
        public int Age
        {
            get;
            set;
        }
    }

  

        static void Main(string[] args)
        {
            SerializationClass serialization = new SerializationClass();
            serialization.Name = "mldark";
            serialization.Age = 24;
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(SerializationClass));
              //序列化
            using (System.IO.FileStream stream = new FileStream("user.xml",FileMode.Create  , FileAccess.Write , FileShare.None))
            {

               serializer.Serialize(stream, serialization);
           
            }

         

            //反序列化
            using (FileStream fileread = new FileStream("user.xml", FileMode.Open))
            {
                serialization = serializer.Deserialize(fileread)as SerializationClass ;

            }

 


          
        }

xml文件生成代码

<?xml version="1.0"?>
<SerializationClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Age="24">
  <Name>mldark</Name>
</SerializationClass>

 

这是最简单xml例子  操作思路就是一个class表示一个根Element 也可以是其他class的一个Element   

那么IXmlSerializable现实自定义序列化

    [Serializable]
    public class serializerList : List<string>, System.Xml.Serialization.IXmlSerializable
    {
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;  
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            if (reader.IsEmptyElement)
                return;
            while (reader.Read() && reader.Name == "add")
            {
                reader.MoveToAttribute("stringValue");
                string val = reader.Value;
                if (val.Length > 0)
                    this.Add(val);

            }
          

        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            foreach(string val in this )
            {
                writer.WriteStartElement("add");
                writer.WriteStartAttribute("stringValue");
                writer.WriteString(val);
                writer.WriteEndAttribute();
                writer.WriteEndElement();
            }
        }
    }

    [Serializable,XmlRoot]
  public class SerializationClass
    {  
     
        [XmlElement]
        public string Name
        {
            get;
            set;
        }
     [XmlAttribute]
        public int Age
        {
            get;
            set;
        }
     [XmlElement]
     public serializerList serializerList;
    }

        static void Main(string[] args)
        {
            SerializationClass serialization = new SerializationClass();
            serialization.Name = "mldark";
            serialization.Age = 24;
            serialization.serializerList = new serializerList();
            serialization.serializerList.Add("1");
            serialization.serializerList.Add("2");
            serialization.serializerList.Add("3");
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(SerializationClass));
              //序列化
            using (System.IO.FileStream stream = new FileStream("user.xml",FileMode.Create  , FileAccess.Write , FileShare.None))
            {

               serializer.Serialize(stream, serialization);
           
            }

         

            //反序列化
            using (FileStream fileread = new FileStream("user.xml", FileMode.Open))
            {
                serialization = serializer.Deserialize(fileread)as SerializationClass ;

            }

      
  }

 

xml文件生成

<?xml version="1.0"?>
<SerializationClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Age="24">
  <serializerList>
    <add stringValue="1" />
    <add stringValue="2" />
    <add stringValue="3" />
  </serializerList>
  <Name>mldark</Name>
</SerializationClass>

.

 

 

原创粉丝点击