zoukankan      html  css  js  c++  java
  • 第二十四章 运行时序列化

    目录:

    24.1 序列化/反序列化快速入门

    24.2 使类型可序列化

    24.3 控制序列化和反序列化

    24.4 格式化器如何序列化类型的实例

    24.5 控制序列化/反序列化的数据

    24.6 流上下文

    24.7 类型序列化为不同类型以及对象反序列化为不同对象

    24.8 序列化代理

    24.9 反序列化对象时重写程序集和/或类型

    序列化是将对象或对象图转换成字节流的过程。反序列化是将字节流转换回对象图的过程:

    应用程序的状态(对象图)可轻松保存到磁盘文件或数据库中,并在应用程序下运行时恢复。ASP.NET就是利用序列化和反序列化来保存和还原会话状态的。

    一组对象可轻松复制到系统的剪切板,在粘贴回同一个或另一个应用程序。

    一组对象可克隆并放到一边作为“备份”;与此同时,用户操纵一组“主”对象。

    一组对象可轻松地通过网络发送给另一台机器上运行的进程。

    24.1 序列化/反序列化快速入门

    BinaryFormatter.Serialize序列化

    BinaryFormatter.Deserialize反序列化

    24.2 使类型可序列化

    使用SerializableAttribute定制特性使对象可序列化,特性不会被派生类型继承。

    24.3 控制序列化和反序列化

     定义不应序列化的实例字段:

    字段含有反序列化后变得无效的信息。如对象包含Windows内核对象(如文件,进程,线程,互斥体,事件,信号量等)的句柄。反序列化到另一个进程或另一台机器之后,就会失去意义。因为Windows内核对象是跟进程相关的值。

    字段含有很容易计算的信息。

    使用System.NonSerializedAttribute定制特性

    24.4 格式化器如何序列化类型的实例

     格式化器自动序列化类型应用了SerializebleAttribute特性的对象:

    1.格式化器调用FormatterServices的GetSerializebleMembers方法:这个方法利用反射获取类型的public和private实例字段。方法返回由MemberInfo对象构成的数组,其中每个元素都对应一个可序列化的实例字段。

    2.对象被序列化,System.Reflection.MemberInfo对象数组传给FormatterServices的静态方法GetObjectData:这个方法返回一个Object数组,其中每个元素都标识了被序列化的那个对象中的一个字段的值。这个Object数组和MemberInfo数组时并行的。

    3.格式化器将程序集标识和类型的完整名称写入流。

    4.格式化器然后遍历两个数组中的元素,将每个成员的名称和值写入流中。

    格式化器自动反序列化类型应用了SerializableAttribute特性的对象:

    1.格式化器从流中读取程序集标识和完整类型名称。如果程序集没有加载到AppDomain中,就加载它。如果程序集已加载,格式化器将程序集标识信息和类型全名传给FormatterServices的静态方法GetTypeFromAssembly:这个方法返回一个System.Type对象,它代表要反序列化的安格对象的类型。

    2.格式化器调用FormatterServices的静态方法GetUninitializedObject:这个方法为一个新对象分配内存,但不为对象调用构造器。对象的所有字节都被初始化为null或0.

    3.格式化器现在构造并初始化一个MemberInfo数组,调用FormatterServices的GetSerializableMember方法。这个方法返回序列化好,现在需要反序列化的一组字段。

    4.格式化器根据流中包含的数据创建并初始化一个Object数组。

    5.将新分配对象,MemberInfo数组以及并行Object数组的引用传给FormatterServices的静态方法PopulateObjectMebers:这个方法遍历数组,将每个字段初始化成对应的值。

    24.5 控制序列化/反序列化的数据

     格式化器序列化对象图时会检查每个对象。如果发现一个对象的类型实现了ISerializable接口,就会忽略所有定制特性,改为构造新的System.Runtime.Serialization.SerializationInfo对象。

    构造SerializationInfo对象时,格式化器要传递两个参数:Type和System.Runtime.Serialization.IFormatterConverter。Type参数标识要序列化的对象。唯一性地标识一个类型需要两个部分的信息:类型的字符串名称及其程序集标识(包括程序集名,版本,语言文化和公钥)。构造好的SerializationInfo对象包含类型的全名,这个字符串会存储到一个私有字段中。构造并初始化好SerializationInfo对象后,格式化器调用类型的GetObjectData方法,向它传递对SerializationInfo对象的引用。

     反序列化:格式化器从流中提取一个对象时,会为新对象分配内存。最初,这个对象的所有字段都设为0或null。然后,格式化器检查类型是否实现了ISerializable接口,如果存在,格式化器就尝试调用一个特殊构造器,它的参数和GetObjectData方法的完全一致。构造器获取一个SerializationInfo对象引用。SerializationInfo对象包含了对象序列化时添加的所有值。

    24.6 流上下文

     StreamingContext:

    成员名称 成员类型 说明
    State StreamingContextStates 一组位标识(big flag),指定要序列化/反序列化的对象的来源或目的地
    Context Object 一个对象引用,对象中包含用户希望的任何上下文信息

    24.7 类型序列化为不同类型以及对象反序列化为不同对象

    有的类型设计成每个AppDomain一个实例。经常将这些类型称为单实例类型。

    反射类型:每个类型和程序集或者成员都只能有个实例。

    对于远程控制的对象,CLR序列化与服务器对象有关的信息。

    24.8 序列化代理

     格式化器还允许不是“类型实现的一部分”的代码重写该类型“序列化和反序列化其对象”的方式。应用程序之所以重写(覆盖)类型的方式:

    允许开发人员序列化最初没有设计成要序列化的类型。

    允许开发人员提供一种方式将类型的一个版本映射到类型的一个不同的版本。

    24.9 反序列化对象时重写程序集和/或类型

     有时需要将对象反序列化成和序列化时不同的类型:

    开发人员可能想把一个类型的实现从一个程序集移动到另一个程序集。

    服务器对象序列化到发送给客服端的流中。客服端处理流时,可以将对象反序列化成完全不同的类型,该类型的代码知道如何向服务器的对象发出远程方法调用。

    开发人员创建了类型的新版本,想把已序列化的对象反序列化成类型的成类型的新版本。

    每天学习一丢丢
  • 相关阅读:
    vue中computed和watch的区别,以及适用场景
    vue中使用过的全局API
    厦门中控
    设置圆角的弧度,保持兼容性
    伪元素::after和::before
    SpringMVC
    mui问题
    错误记录
    Android错误
    Android之界面(布局文件layput)
  • 原文地址:https://www.cnblogs.com/terry-1/p/10481096.html
Copyright © 2011-2022 走看看