.NET简谈组件程序设计之(初识序列化、持久化)

 今天我们来学习在组件开发中经常用到的也是比较重要的技术“序列化”。

序列化这个名词对初学者来说不太容易理解,有点抽象。我们还是用传统的分词解释吧,肯定能搞懂它的用意是什么。

解释:数学上,序列是被排成一列的对象(或事件);这样,每个元素不是在其他元素之前,就是在其他元素之后。这里,元素之间的顺序非常重要。

那么我们对照这样的解释来分析一下我们程序中的序列化什么意思。都知道对象的状态是在内存中实时存着的,对象的状态在初始化的时候是通过系统分配的,在后期的程序运行过程中可能对它进行过一些修改,那么我们怎样将这些状态保存下来供下次使用呢。[王清培版权所有,转载请给出署名]

.NET中的序列化是将内存中的对象状态转换成某种有规律的序列,这样的序列可以是二进制的,也可以是XML形式的,也可以是SOAP形式的。.NET也提供了我们可以自己实现序列化的接口。

在.NET里面,我们可以很方便的通过系统提供给我们的工具进行序列化对象。那么序列化的作用是干嘛的呢?文章的标题提到了“持久化”的名词,那么持久化又是什么呢?

解释:持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。 

通过序列化将对象状态进行持久化,在必要的时候我们可以很方便的进行对象复活。好了理论我们就不讲了,来看看代码怎么实现。

Serializable特性

using System.Runtime.InteropServices;

namespace System
{
    // 摘要:
    //     指示一个类可以序列化。无法继承此类。
    [ComVisible(true)]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]
    public sealed class SerializableAttribute : Attribute
    {
        // 摘要:
        //     初始化 System.SerializableAttribute 类的新实例。
        public SerializableAttribute();
    }
}

 

 

这是Serializable特性的定义,通过使用Serializable特性进行标记类、结构、枚举、委托。那么就可以使用格式化器进行序列化了,没有被Serializable特性标记的对象无法进行序列化,在序列化的时候会抛出异常。[王清培版权所有,转载请给出署名]

IFormatter格式器接口

iformatter接口是序列化格式器,通过实现该接口提供序列化功能。系统提供给我们的序列化功能对象(BinaryFormatter、SoapFormatter)都是实现了该接口。

图1:

 



还有一个XmlSerializer 序列化对象是在XML命名空间下的,主要是高扩展性的接口,我们可以扩展它进行复杂的XML序列化。上图中的两个Iformatter接口实现类(Binarymatter、SoapMatter)都已经帮我们实现了复杂的二进制序列化和Soap序列化,我们只需要通过简单的使用它们就行了。[王清培版权所有,转载请给出署名]

使用Serializable特性、IFormatter接口进行序列化对象 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace ConsoleApplication1.序列化和持久化
{
    [Serializable]
    public class MyClass
    {
        public MyClass() { }
        public string number = "MyClass状态";

    }
}

 

 二进制序列化:

 IFormatter formatter = new BinaryFormatter();
            Stream stream = new FileStream("obj.bin", FileMode.Create, FileAccess.Write);
            using (stream)
            {
                formatter.Serialize(stream, new MyClass());
            }
            //反序列化
            Stream stream1 = new FileStream("obj.bin", FileMode.Open, FileAccess.Read);
            using (stream1)
            {
                MyClass mycalss = formatter.Deserialize(stream1) as MyClass;
            }

 

SOAP序列化:

SoapFormatter formatter = new SoapFormatter();

            Stream stream = new FileStream("obj.xml", FileMode.Create, FileAccess.Write);
            using (stream)
            {
                MyClass myclass = new MyClass();

                formatter.Serialize(stream, myclass);
            }

            Stream stream1 = new FileStream("obj.xml", FileMode.Open, FileAccess.Read);
            using (stream1)
            {
                MyClass myclass = formatter.Deserialize(stream1) as MyClass;
            }

 

 使用Iformatter接口序列化对象时我们只需要提供了Stream流对象就行了。将对象序列化到文件流(FileStream)、内存流(MemoryStream)、网络流(NetworkStream)都可以。

使用NonSerialized禁止成员序列化

在对象的内部我们可能需要禁止一些成员被序列化。在序列化的对象的时候,系统是递归的序列化对象内部的每一个成员,如果有一个对象是不允许序列化的,也就是没有加上Serializable特性的。那么在序列化的时候就会失败。至少我们需要能控制它的序列化过程的手动才行。请看代码:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1.序列化和持久化
{
    public class MyChildClass
    {
        public string name = "MyChildClass状态";
    }
}

 

 这个对象我没有加上序列化特性标记。

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace ConsoleApplication1.序列化和持久化
{
    [Serializable]
    public class MyClass : IDeserializationCallback, ISerializable
    {
        public MyClass() { }
        public string number = "MyClass状态";

        public MyChildClass ChildClass;

    }
}

 

 这里我需要序列化MyChildClass对象。

图2:

 

这里就报错了。

那么我们给对象MyChildClass字段加上禁止序列化标记。

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace ConsoleApplication1.序列化和持久化
{
    [Serializable]
    public class MyClass : IDeserializationCallback, ISerializable
    {
        public MyClass() { }
        public string number = "MyClass状态";

        [NonSerialized]
        public MyChildClass ChildClass;

    }
}

 

 

图3:

 

 

顺利通过序列化。[王清培版权所有,转载请给出署名]

 

这篇文章主要让我们了解下关于序列化的一些基本概念和使用方法。下一篇文章我们将学习怎样切入到序列化的内部进行一些序列化过程的控制。

时间: 2024-10-25 03:00:55

.NET简谈组件程序设计之(初识序列化、持久化)的相关文章

.NET简谈组件程序设计之(渗入序列化过程)

在本人的上一篇文章".NET简谈组件程序设计之(初识序列化.持久化) "中,我们基本上了解了什么叫序列化和持久化.通过系统为我们提供的服务,我们可以很方便的进行二进制序列化.SOAP协议序列化. 今天这篇文章是来讲解怎么运用一些高级的功能,在序列化.反序列化过程中进行一些控制.[王清培版权所有,转载请给出署名] 这里穿插一句题外话:其实在我们自己编写组件的时候真的有好多东西可以借鉴.NET平台的一些优点,它的功能都不是死的,可以订阅.可以切入,在我们编写组件的时候,我们其实也要好好考虑

.NET简谈组件程序设计之(初识NetRemoting)

在本人的".NET简谈组件程序设计之(初识远程调用)  "一文中,我们了解到什么是远程调用或者说在.NET平台上远程调用是什么样子的,可能和偏低层(Socket\Rpc)的远程调用有点距离.这只是系统为我们封装了假象而已,看不见不代表没有这逻辑,是为我们减轻了劳动负担.[王清培版权所有,转载请给出署名] 这篇文章我们来简单的了解一下在.NET平台上有一个强有力的远程调用武器,也是上一篇文章中我一笔带过的远程英雄.NetRemoting. 其实在.NET平台里面到处都能看见Remotin

.NET简谈组件程序设计之(初识.NET线程Thread)

由于多线程的内容比较多我会用几篇文章来讲解. 多线程在我们日常开发过程中用的很多,上一篇".NET简谈组件程序设计之(异步委托) "详细的讲解了基于委托的多线程使用,委托是基于后台线程池的原理,这篇文章将主要介绍直接使用Thread对象来实现多线程. 当然使用Thread没有使用Delegate那么容易,毕竟多线程跟异步调用是两个相差很大的技术方向,我也是略懂点皮毛,在此献丑给大家,如有讲的不对的地方还请指出.[王清培版权所有,转载请给出署名] 我们先来理解几个概念,以方便我们学习.

.NET简谈组件程序设计之(初识远程调用)

在.NET1.0版本出来的时候,要想进行远程调用基本上都是通过WebService的方式.而随着.NET2.0版本的出现,我们可以通过一个更加方便且高扩展性的框架来进行编写远程调用的程序,也就是我们都比较熟悉的.NetRemoting. 网上对.NetRemoting技术讲解的文章不计其数,但是很少有一本比较全面的.系统的学习书籍.我们都是从哪些零散的知识里慢慢摸索,效果不太理想. 今天我也来简单的介绍一下我理解的Remoting.不仔细研究一下还真不知道它的厉害,完全的托管平台.高扩展性.灵活

.NET简谈组件程序设计之(上下文与同步域)

我们继续学习.NET多线程技术,这篇文章的内容可能有点复杂.在打破常理之后,换一种新的思考模型最为头疼.这篇文章里面会涉及到一些不太常见的概念,比如:上下文.同步域等等.我也是最近才接触这些关于组件编程方面的高深技术,大家一起学习,再大的困难也是有时间限制的,只要我们坚持. 在本人的上一篇文章".NET简谈组件程序设计之(多线程与并发管理一)"中,只是初步的带领我们学习一下关于多线程的一些基本的原理,包括线程切换,线程的开始.执行.等待.结束. 这篇文章的重点是学习关于线程的同步.互斥

.NET简谈组件程序设计之(手动同步)

在上一篇文章".NET简谈组件程序设计之(上下文与同步域)"中,我们学习了关于一些上下文和同步域的概念,可以利用这两个技术来进行自动同步. 今天我们主要学习怎么手动来执行同步,能从更小的粒度进行封锁,以达到最大程度的吞吐量.[王清培版权所有,转载请给出署名] 我们知道线程是进程的运行实体,进程是资源分配单位,而线程是执行单位.照书上所说,线程是程序的执行路径,当我们分配一个线程的时候,要确定线程的执行路径是什么,也就是代码中的ThreadStart委托所指向的入口点方法. 一旦我们手动

.NET简谈组件程序设计之(delegate与event关系)

 本人最近一段时间在学习关于.NET组件编程方面的技术,在学习过程中确实有很多好的东西需要与大家分享.[王清培版权所有,转载请给出署名] 关于什么叫组件编程,其实就是利用.NET来开发基于组件模型的程序,面向组件编程而非面向对象编程,这是一个高度,没有很长时间的学习与磨练 是体会不到这个感觉的.我们现在的开发思想应该是以面向对象为主的,但是如何提升这个高度,只有慢慢的学习了. 其实面向组件编程包含了面向对象编程思想,将一组功能独立的封装起来供以后重复使用,但是在开发组件的过程中需要使用到面向对象

.NET简谈组件程序设计之(详解NetRemoting结构)

在本人的上一篇文章中只是简单的介绍了一下.NETRemoting的一般概念和基本的使用.这篇文章我想通过自己的学习和理解将对.NETRemoting的整体的一个框架进行通俗的讲解,其中最重要的就是信道(管道)处理模型思想,这里面蕴含了很多的设计原理.[王清培版权所有,转载请给出署名].NETRemoting远程处理架构是一个半成品,是.NET给我们的扩展框架,要想用于商业项目必须进行一些安全.性能方面的控制.要想进行一定深度的扩展那就要必须了解它的整体结构,各个点之间的关系才能很好的控制它. 网

.NET简谈组件程序设计之(AppDomain应用程序域)

最近在苦学.NET底层框架模型,发现.NET深入真的不是一般的难,不开源.没有相关系统的官方的书籍做学习资料,只能零散的看MSDN.要想摸熟.NET的模型真的并非易事.慢慢来吧.[王清培版权所有,转载请给出署名] .NET应用程序域(AppDomain)是我们所有.NET应用程序的逻辑宿主容器.初次接触会感觉到AppDomain离我们日常开发比较远,不常用到.其实是我们很少接触一些复杂而底层的系统结构.在日常的开发中,我们多数是基于数据库的管理信息系统(MIS),做增.删.改.查的操作.我始终认