• c#序列化及反序列化(三种方式)


    一:BinaryFormatter序列化

    序列化简单点来理解就是把内存的东西写到硬盘中,当然也可以写到内存中(这个内容我会在后面写一个例子).而反序列化就是从硬盘中把信息读到内存中.就这么简单,呵呵,现在来看下面的例子吧!

    在这篇文章中我将使用BinaryFormatter序列化类Book作为例子,希望大家能从例子中深刻体会什么是序列化.

    定义类Book:

    [Serializable]
    public class Book
    {
        string name;
        float      price;
        string author;

        public Book(string bookname, float bookprice, string bookauthor)
        {
         name = bookname;
         price = bookprice;
         author = bookauthor;
        }
    }

    在类的上面增加了属性:Serializable.(如果不加这个属性,将抛出SerializationException异常).

    通过这个属性将Book标志为可以序列化的.当然也有另一种方式使类Book可以序列化,那就是实行ISerializable接口了.在这里大家要注意了:Serializable属性是不能被继承的咯!!!

    如果你不想序列化某个变量,该怎么处理呢?很简单,在其前面加上属性[NonSerialized] .比如我不想序列化

    string author;

    那我只需要

    [NonSerialized]

    string author;

    好了,现在就告诉大家怎么实现序列化:

    我们使用namespace:

    using System;

    using System.IO;

    using System.Runtime.Serialization.Formatters.Binary;

    首先创建Book实例,like this:  

    Book book = new Book("Day and Night", 30.0f, "Bruce");

    接着当然要创建一个文件了,这个文件就是用来存放我们要序列化的信息了.

    FileStream fs = new FileStream(@"C:/book.dat", FileMode.Create);

    序列化的实现也很简单,like this:

          BinaryFormatter formatter = new BinaryFormatter();
          formatter.Serialize(fs, book);

    很简单吧!现在我列出整个原代码,包括反序列化.

        static void Main(string[] args)
        {
         Book book = new Book("Day and Night", 30.0f, "Bruce");

         using(FileStream fs = new FileStream(@"C:/book.dat", FileMode.Create))
         {
          BinaryFormatter formatter = new BinaryFormatter();
          formatter.Serialize(fs, book);
         }

         book = null;

         using(FileStream fs = new FileStream(@"C:/book.dat", FileMode.Open))
         {
          BinaryFormatter formatter = new BinaryFormatter();
          book = (Book)formatter.Deserialize(fs);//
    在这里大家要注意咯,他的返回值是object
         }
        }


    二、SoapFormatter序列化方式 
    调用序列化和反序列化的方法和上面比较类似,我就不列出来了,主要就看看SoapSerialize类 
    SoapSerialize类 
    using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using System.IO; 
    using System.Runtime.Serialization.Formatters.Soap; 

    namespace SerializableTest 

         public class SoapSerialize 
         { 
             string strFile = /"c:////book.soap/"; 

             public void Serialize(Book book) 
             { 
                 using (FileStream fs = new FileStream(strFile, FileMode.Create)) 
                 { 
                     SoapFormatter formatter = new SoapFormatter(); 
                     formatter.Serialize(fs, book); 
                 } 
             } 

             public Book DeSerialize() 
             { 
                 Book book; 
                 using (FileStream fs = new FileStream(strFile, FileMode.Open)) 
                 { 
                     SoapFormatter formatter = new SoapFormatter(); 
                     book = (Book)formatter.Deserialize(fs);

     


                 } 
                 return book; 
             } 
         } 

    主要就是调用System.Runtime.Serialization.Formatters.Soap空间下的SoapFormatter类进行序列化和反序列化,使用之前需要应用System.Runtime.Serialization.Formatters.Soap.dll(.net自带的) 
    序列化之后的文件是Soap格式的文件(简单对象访问协议(Simple Object Access Protocol,SOAP),是一种轻量的、简单的、基于XML的协议,它被设计成在WEB上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。SOAP使用基于XML的数据结构和超文本传输协议(HTTP)的组合定义了一个标准的方法来使用Internet上各种不同操作环境中的分布式对象。) [Page]
    调用反序列化之后的结果和方法一相同 


    三、XML序列化方式 
    调用序列化和反序列化的方法和上面比较类似,我就不列出来了,主要就看看XmlSerialize类 
    XmlSerialize类 
    using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using System.IO; 
    using System.Xml.Serialization; 

    namespace SerializableTest 

         public class XmlSerialize 
         { 
             string strFile = /"c:////book.xml/"; 

             public void Serialize(Book book) 
             { 
                 using (FileStream fs = new FileStream(strFile, FileMode.Create)) 
                 { 
                     XmlSerializer formatter = new XmlSerializer(typeof(Book)); 
                     formatter.Serialize(fs, book); 
                 } 
             } 

             public Book DeSerialize() 
             { 
                 Book book; 
                 using (FileStream fs = new FileStream(strFile, FileMode.Open)) 
                 { 
                     XmlSerializer formatter = new XmlSerializer(typeof(Book)); 
                     book = (Book)formatter.Deserialize(fs); 
                 } 
                 return book; 
             } 
         } 

    从这三个测试类我们可以看出来其实三种方法的调用方式都差不多,只是具体使用的类不同 
    xml序列化之后的文件就是一般的一个xml文件: 
    book.xml 
    <?xml version=/"1.0/"?> 
    <Book xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/"> 
       <strBookName>C#强化</strBookName> 
       <strBookPwd>*****</strBookPwd> 
       <alBookReader> 
         <anyType xsi:type=/"xsd:string/">gspring</anyType> 
         <anyType xsi:type=/"xsd:string/">永春</anyType> 
       </alBookReader> 
       <BookID>1</BookID> 
    </Book>输出截图如下: 

    也就是说采用xml序列化的方式只能保存public的字段和可读写的属性,对于private等类型的字段不能进行序列化 

    关于循环引用: 
    比如在上面的例子Book类中加入如下一个属性: 
             public Book relationBook; 
    在调用序列化时使用如下方法: 
                 Book book = new Book(); 
                 book.BookID = /"1/"; [Page]
                 book.alBookReader.Add(/"gspring/"); 
                 book.alBookReader.Add(/"永春/"); 
                 book.strBookName = /"C#强化/"; 
                 book.strBookPwd = /"*****/";

                book.SetBookPrice(/"50.00/"); 

                 Book book2 = new Book(); 
                 book2.BookID = /"2/"; 
                 book2.alBookReader.Add(/"gspring/"); 
                 book2.alBookReader.Add(/"永春/"); 
                 book2.strBookName = /".NET强化/"; 
                 book2.strBookPwd = /"*****/"; 
                 book2.SetBookPrice(/"40.00/"); 

                 book.relationBook = book2; 
                 book2.relationBook = book; 
                 BinarySerialize serialize = new BinarySerialize(); 
                 serialize.Serialize(book);这样就会出现循环引用的情况,对于BinarySerialize和SoapSerialize可以正常序列化(.NET内部进行处理了),对于XmlSerialize出现这种情况会报错:/"序列化类型 SerializableTest.Book 的对象时检测到循环引用。/"


  • 相关阅读:
    (转)样本方差的期望
    (转)Python 字典排序
    曝光补偿
    python判断字符串是否包含子字符串
    python requests接口测试 -----博客园串接口
    jmeter+ant+jenkins 搭建接口自动化测试
    TOMCAT闪退。cmd执行startup.bat保错:the CATALINA_HOME environment variable is not defined correctly
    selenium python自动化测试 ddt数据驱动
    jenkins到底如何拉取代码 如何部署的
    git 常用命令
  • 原文地址:https://www.cnblogs.com/fornet/p/2976161.html
Copyright © 2020-2023  润新知