• [.net 面向对象程序设计进阶] (9) 序列化(Serialization) (一) 二进制流序列化


    [.net 面向对象程序设计进阶]  (9)  序列化(Serialization) (一) 二进制流序列化 

    本节导读: 

    在.NET编程中,经常面向对象处理完以后要转换成另一种格式传输或存储,这种将对象转向其他数据格式的过程,即序列化(Serialization)。 

    与之相反的过程就是反序列化(Deserialization)。掌握和利用好序列化和反序列化的方法,对提高面向编程技术很有益处。 

    读前必备: 

    A.类和类的实例  [.net 面向对象编程基础]  (9) 类和类的实例 

    B.类的成员        [.net 面向对象编程基础]  (10) 类的成员(字段、属性、方法)

    1. 什么是序列化和反序列化? 

    序列化(Serialization):序列化是将对象状态转换为可保持或传输的格式的过程。 

    反序列化(Deserialization) :与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。 

    MFC中储存或恢复对象的过程即为Serialization,也称为Persistent(永续生存)。在序列化期间,对象将其当前状态写入到临时或永久性存储区(存入文件中)。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。以此达到面向对象中的永续生存。

    2. .NET中的序列化技术 

    .NET Framework 几种序列化技术,主要有以下几种: 

    严格来说只有两种,就是二进制序列化,和使用数据格式协定的序列化(包含XML,SOAP.JSON等) 

    A. 二进制(流)序列化(BinaryFormatter) -->(C/S方向为主) 

    二进制序列化保持类型保真度,用于在应用程序的不同调用之间保留对象的状态。 

    例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流、磁盘、内存和网络等等。远程处理使用序列化“通过值”在计算机或应用程序域之间传递对象。 

    B. XML 序列化(XmlSerializer) -->(B/S C/S通用) 

    XML序列化仅序列化公共属性和字段,且不保持类型保真度。对于要提供或使用数据而不限制使用该数据的应用程序时,比较有用的。由于 XML 是一个开放式标准,因此,对于通过 Web 共享数据而言,这是一个很好的选择。

    C. SOAP序列化(SoapFormatter) -->(通用,主要用于WebSerice交换数据) 

     SOAP同样是一个开放式标准,这SOAP协议是一个在异构的应用程序之间进行信息交互的理想的选择 

    D. WCF协议序列化(DataContractSerializer)-->(B/S方向,主要用于WCF通讯) 

    F. Json序列化 (DataContractJsonSerializer-->(B/S移动开发 方向) 

    Json全称是 JavaScript 对象表示法(JavaScript Object Notation))是一种轻量级的数据交换方式。

    3. 二进制(流)序列化 

    本节主要介绍二进制(流)序列化 

    二进制(流)序列化,主要在底层(相对)通讯中使用比较频繁,我们知道计算机是通过二进制将数据传输和存储到媒介(硬盘等),那么我们在进行面向对象编程中,如何准确快速的将对象实例转换为二进制流,就是我们这节要介绍的内容。 

    对象=》二进制流 即二进制流序列化 

    下面,我还是使用“基础篇”中“武林高手”的类来 通过“文件流”创建文件。 

    首先创建数据类及序列化方法,如下: 

    注意一下:[Serializable]标识 

    Serializable属性用来明确表示该类可以被序列化。

    同样的,我们可以用NonSerializable属性用来明确表示类不能被序列化。

    /// <summary>
    /// 类:武林高手
    /// MartialArtsMaster
    /// </summary>
    [Serializable]
    class MartialArtsMaster
    {
        /// <summary>
        /// 编号
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }
        /// <summary>
        /// 门派
        /// </summary>
        public string Menpai { get; set; }
        /// <summary>
        /// 武学
        /// </summary>
        public string Kungfu { get; set; }
        /// <summary>
        /// 级别
        /// </summary>
        public int Level { get; set; }
    }
    
    /// <summary>
    /// 二进制序列化和反序列化类
    /// </summary>
    public class Serializer
    {
        /// <summary> 
        /// 使用二进制序列化对象。 
        /// </summary> 
        /// <param name="value"></param> 
        /// <returns></returns> 
        public static byte[] SerializeBytes(object value)
        {
            if (value == null) return null;
    
            var stream = new MemoryStream();
            new BinaryFormatter().Serialize(stream, value);
    
            //var dto = Encoding.UTF8.GetString(stream.GetBuffer()); 
            var bytes = stream.ToArray();
            return bytes;
        }
    
        /// <summary> 
        /// 使用二进制反序列化对象。 
        /// </summary> 
        /// <param name="bytes"></param> 
        /// <returns></returns> 
        public static object DeserializeBytes(byte[] bytes)
        {
            if (bytes == null) return null;
    
            //var bytes = Encoding.UTF8.GetBytes(dto as string); 
            var stream = new MemoryStream(bytes);
    
            var result = new BinaryFormatter().Deserialize(stream);
    
            return result;
        }
    }

    下面是调用方法:

    //本例命名空间
    //using System.Runtime.Serialization.Formatters.Binary;
    //using System.IO;
    
    //初始化武林高手
    var master = new List<MartialArtsMaster>(){
        new MartialArtsMaster(){ Id = 1, Name = "黄蓉",    Age = 18, Menpai = "丐帮", Kungfu = "打狗棒法",  Level = 9  },
        new MartialArtsMaster(){ Id = 2, Name = "洪七公",  Age = 70, Menpai = "丐帮", Kungfu = "打狗棒法",  Level = 10 },
        new MartialArtsMaster(){ Id = 3, Name = "郭靖",    Age = 22, Menpai = "丐帮", Kungfu = "降龙十八掌",Level = 10 },
        new MartialArtsMaster(){ Id = 4, Name = "任我行",  Age = 50, Menpai = "明教", Kungfu = "葵花宝典",  Level = 1  },
        new MartialArtsMaster(){ Id = 5, Name = "东方不败",Age = 35, Menpai = "明教", Kungfu = "葵花宝典",  Level = 10 },
        new MartialArtsMaster(){ Id = 6, Name = "林平之",  Age = 23, Menpai = "华山", Kungfu = "葵花宝典",  Level = 7  },
        new MartialArtsMaster(){ Id = 7, Name = "岳不群",  Age = 50, Menpai = "华山", Kungfu = "葵花宝典",  Level = 8  }
    };
    
    //文件流写入
    using (FileStream fs = new FileStream(@"F:360同步云盘360同步云盘博客序列化master.obj", FileMode.Append))
    {
        var myByte = Serializer.SerializeBytes(master);
        fs.Write(myByte, 0, myByte.Length);
        fs.Close();
    };
    
    //文件流读取
    using (FileStream fsRead = new FileStream(@"F:360同步云盘360同步云盘博客序列化master.obj", FileMode.Open))
    {
        int fsLen = (int)fsRead.Length;
        byte[] heByte = new byte[fsLen];
        int r = fsRead.Read(heByte, 0, heByte.Length);
        var myObj = Serializer.DeserializeBytes(heByte) as List<MartialArtsMaster>;
        Console.WriteLine("编号---姓名---年龄---门派---武功---等级");
        myObj.ForEach(m => 
            Console.WriteLine(m.Id + "---" + m.Name + "---" + m.Age + "---" + m.Menpai + "---" + m.Kungfu + "---" + m.Level)
        );  
    }

    运行结果如下:

    首先是创建的文件master.obj:

     读取运行结果如下: 

    4.要点: 

    A.序列化和反序列化的理解:

    序列化(Serialization):序列化是将对象状态转换为可保持或传输的格式的过程。

    反序列化(Deserialization) :与序列化相对的是反序列化,它将流转换为对象。

    B. .NET中的序列化技术

      注明了主要使用方向,方便小伙伴们有选择性的学习。

    (1)二进制(流)序列化( BinaryFormatter) -->(C/S方向为主)

    (2)XML 序列化(XmlSerializer) -->(B/S C/S通用)

    (3)SOAP序列化(SoapFormatter -->(通用,主要用于WebSerice交换数据)

    (4)WCF协议序列化(DataContractSerializer)-->(B/S方向,主要用于WCF通讯)

    (5) Json序列化 (DataContractJsonSerializer)-->(B/S移动开发 方向)

    ==============================================================================================  

     返回目录

     <如果对你有帮助,记得点一下推荐哦,如有有不明白或错误之处,请多交流>  

    <对本系列文章阅读有困难的朋友,请先看《.net 面向对象编程基础》>

    <转载声明:技术需要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>

    .NET 技术交流群:467189533    .NET 程序设计

    ==============================================================================================   

  • 相关阅读:
    BZOJ3501 : PA2008 Cliquers Strike Back
    BZOJ3500 : PA2008 Cliquers
    BZOJ2280 : [Poi2011]Plot
    BZOJ2924 : [Poi1998]Flat broken lines
    BZOJ2911 : [Poi1997]The Number of Symmetrical Choices
    BZOJ2612 : [Poi2003]Sums
    BZOJ4025 : 二分图
    BZOJ2213 : [Poi2011]Difference
    BZOJ2215 : [Poi2011]Conspiracy
    BZOJ2278 : [Poi2011]Garbage
  • 原文地址:https://www.cnblogs.com/yubinfeng/p/4631379.html
Copyright © 2020-2023  润新知