第24章 运行时序列化

什么是序列化和反序列化

序列化(serialization)是将一个对象或者对象图(对象在特定的时间点的一个视图)转换成一个字节流的过程。反序列化(deserialization)是将一个字节流转换回对象图的过程。

应用场景:

  • 应用程序的状态(对象图)可以保存到磁盘文件或数据库中,并在应用程序下次运行时恢复。
  • 一组对象可以轻松复制到Windows 窗体的剪贴板中,再粘贴回同一个或者另一个应用程序。
  • 将对象按值从一个应用程序域中发送到另一个程序域

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

http://blog.csdn.net/gavinchengshubo/article/details/8378441

引用 System.Runtime.Serialization.Formatters.Binary

private static MemoryStream SerializeToMemory(object objectGraph) {
    MemoryStream stream = new MemoryStream();
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(stream, objectGraph);
    return stream;
}
private static Object DeserializeFormMemory(Stream stream) {
    BinaryFormatter formatter = new BinaryFormatter();
    return formatter.Deserialize(stream);
}
static void Main(string[] args)
{
    List<string> objectGraph = new List<string> {"hzd","ian.w","whx1973" };
    Stream stream = SerializeToMemory(objectGraph);
    stream.Position = 0;
    objectGraph = null;
    objectGraph = (List<string>)DeserializeFormMemory(stream);
    foreach (var s in objectGraph)
    {
        Console.WriteLine(s);
    }
}

SerializeToMemory方法创建MemoryStream对象,用来做序列化完成后字节存在的容器,创建BinaryFormatter对象formatter(格式化器),调用Serialize方法,传递一个流对象的引用和要被序列化的对象的引用。流对象可以是任何一个从System.IO.Stream抽象基类派生的任何类型的一个对象 (MemoryStream,FileStream,NetworkSteam),第二个参数可以是任何东西,如Int32 、String、List<String>等等
DeserializeFormMemory 方法创建 BinaryFormatter 对象 formatter,调用 Deserialize 方法,此方法获取流作为参数,返回对反序列化的对象图中的根对象的一个引用。在内部,格式化器的
Deserialize方法会检查流的内容,够造流中的所有对象的实例,并初始化所有这些对象的字段,使它们具有与当初序列化时相同的值。通常要将Deserialize方法返回的对象引用转型为应用程序期待的类型。使类型可序列化类型默认是不可以序列化的,需要定制System.SerializableAttributeattribute(此attributeSystem命名空间定义的),SerializableAttribute这个定制attribute只能应用于引用类型(class)、值类型(struct)、枚举类型(enum)和委托类型(delegate)。此外SerializableAttribute attribute不会被派生类继承
控制序列化和反序列化SerializableAttribute 这个定制的attribute应用于一个类型时,所有的实例字段(public private protected 等)都会被序列化。使用System.NonSerializedAttribute 定制attribute来指明类型的哪些字段不应序列化。此attribute同样位于System命名空间

[Serializable]
internal class Circle
{
    private double m_radius;
    [NonSerialized]
    private Double m_area;

    public Circle(double radius)
    {
        m_radius = radius;
        m_area = Math.PI * m_radius * m_radius;
    }
}

上述代码中,Circle的对象可以序列化 ,然而反序列化时,Circle对象的 m_area 字段会被设置为 0 ,不能得到正确的结果,修改上面的代码为 

[Serializable]
internal class Circle
{
    private double m_radius;
    [NonSerialized]
    private Double m_area;

    public Circle(double radius)
    {
        m_radius = radius;
        m_area = Math.PI * m_radius * m_radius;
    }
    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
        m_area = Math.PI * m_radius * m_radius;
    }
}

在修改的代码中 ,包含了一个用 System.Runtime.Serialization.OnDeserializedAttribute定制的 特性 进行了标记的方法 ,每次反序列化类型的一个实例 ,格式化器都会检查类型中是否定义了一个应用该特性的方法 。除了 OnDeserializedAttribute这个定制的特性 ,System.Runtime.Serialization命名空间还包含 OnDeserializingAttribute,OnSerializingAttribute,OnSerializedAttribute这些定制的attribute。

时间: 2024-10-12 13:10:22

第24章 运行时序列化的相关文章

Delphi知识点与技术概述【第二章 运行时库(RTL)】

内容提要: *RTL概述 运行时库简称RTL,是一个非常庞大的函数集合. RTL的单元 SysUtils与SySConst单元 Sysconst单元定义了一些由其他RTL单元显示消息的常量字符串,这些字符串用resourcestring关键字来声明,并保存在程序资源中.它一些特性我们经常使用,如:IntToStr或Format,windows版本信息等. 时间日期操作,不会引起异常. TryStrToDate 将字符串转换为日期 TryEncodeDate 对日期进行编码 TryEncodeTi

【C#进阶系列】24 运行时序列化

序列化是将对象或者对象图(一堆有包含关系的对象)转换成字节流的过程.而反序列化就是将字节流转为对象或对象图. 主要用于保存.传递数据,使得数据更易于加密和压缩. .NET内建了出色的序列化和反序列化支持. 上一个简单的小例子: using System.Runtime.Serialization.Formatters.Binary; namespace MyTest { class Program { static void Main(string[] args) { MemoryStream

C# 运行时序列化

一. 序列化与反序列的作用 为什么要有序列化呢,考虑下面这种情况,在WINFORM或者更为方便的WPF工程中,当我们进行UI设计时,可以随意的将一个控件剪切/张贴到另外一个地方.操作方便的背后是什么在发挥作用呢.控件明明是一个复杂的对象,却可以进行剪切张贴.这其中就涉及到了对象的转换.将控件这个复杂的对象转换为字节流,进行复制,然后再将字节流反转为控件对象.这样就实现了控件的随意剪切与张贴. 上述就体现了序列化的应用场合,数据传送. 定义: 序列化:将对象转换为字节流. 反序列化:将字节流转换为

第二章 运行时的页面构建过程

1.客户端 Web 应用的生命周期 客户端 Web 应用的生命周期从用户指定某个网站地址(或单击某个链接)开始 其由两个步骤组成:页面构建和事件处理 页面构建 -- 创建用户界面 事件处理 -- 进入循环(序号5)从而等待事件(序号6)的发生,发生后调用事件处理器 2.页面构建阶段 页面构建阶段从浏览器接收页面代码开始 其执行分为两个步骤: (1).解析 HTML 代码并构建文档对象模型(DOM) (2).执行 Javascript 代码 步骤 1 会在浏览器处理 HTML 节点的过程中执行 步

Android 6.0 运行时权限管理

android 6.0 对权限进行了严格的管理 新的权限策略讲权限分为两类,第一类是不涉及用户隐私的,只需要在Manifest中声明即可,比如网络.蓝牙.NFC等:第二类是涉及到用户隐私信息的,需要用户授权后才可使用,比如SD卡读写.联系人.短信读写等. Normal Permissions 此类权限都是正常保护的权限,只需要在AndroidManifest.xml中简单声明这些权限即可,安装即授权,不需要每次使用时都检查权限,而且用户不能取消以上授权,除非用户卸载App. ACCESS_LOC

[Phonegap+Sencha Touch] 移动开发24 打包wp8.1的App,运行时输入框聚焦弹出软键盘之后,界面上移而不恢复原位的解决办法

这个现象只出现在phonegap打包sencha touch的wp8.1程序会出现(仅wp8.1,wp8正常),其它js框架我测试了几个(app framework, jquery mobile),好像没有这个问题. 我来描述一下这个现象: 1.运行phonegap打包的wp8程序,打开一个有输入框的界面,如下图: 2.点击输入框,使其弹出软键盘,界面会上移,如下图: 3.点返回键隐藏软键盘(或者点击界面上其它地方隐藏软键盘),此时界面不恢复原位,如下图: 我的一些研究结果: 1.这种现象只出现

第十九章 排查和调试Web程序 之 防止和排查运行时问题

1. 概述 常见的几种运行时问题包括 错误数据.慢于预期的响应.未知行为 或者 未处理的异常. Visual Studio 提供了 排查.跟踪 和 日志 等工具 来帮助排查系统的问题.有些情况还需要插入诊断代码. 本章内容包括:排查性能.安全问题和运行时错误, 实现跟踪.日志(包括使用attributes) 和 调试(包括 IntelliTrace),使用代码契约来加强条件验证,启用和配置健康监视. 2. 主要内容 2.1 排查性能问题.安全问题和运行时错误 性能问题会让用户有挫败感 安全问题可

《精通C#》第十六章-动态类型和动态语言运行时-第一节至第四节

在.Net4.0中引入了一个关键字dynamic,这是一个动态类型关键字.Net中还有一个关键字是var,这是一个隐式类型,可以定义本地变量,此时var所代表的实际的数据类型有编译器在初次分配时决定,比如:var a=1:a="aa":此时编译器就会报错,因为var在初次定义是已经被分配为int类型,它无法用于返回值.参数或者类/结构.这个时候就要想到所有类型的父类object,按照继承关系来说,object是所有类型的父类,所以它可以替代所有的类,也就是说:object a=1:a=

第二章 1.运行时数据区域

[TOC 概述 对于从事C.C++的程序开发人员来说,在内存管理领域,担负着每一个对象生命开始到终结的责任. 对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不需要为为每一个new操作去写配对的delete/free代码,不容易出现内存泄漏和内存溢出问题,由虚拟机管理内存这一切看起来都很美好.不过,也正是因为Java程序员把内存控制的权利交给了Java虚拟机,一旦出现内存泄漏和溢出的问题,如果不了解虚拟机是如何管理内存的,那么排查错误将会成为一项异常艰难的工作. 运行时数据区简介 Ja