.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:

 

 

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

 

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

目录
相关文章
|
1天前
|
云安全 监控 安全
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
820 5
|
12天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
1053 37
|
8天前
|
机器学习/深度学习 人工智能 数据可视化
1秒生图!6B参数如何“以小博大”生成超真实图像?
Z-Image是6B参数开源图像生成模型,仅需16GB显存即可生成媲美百亿级模型的超真实图像,支持中英双语文本渲染与智能编辑,登顶Hugging Face趋势榜,首日下载破50万。
620 36
|
12天前
|
人工智能 前端开发 算法
大厂CIO独家分享:AI如何重塑开发者未来十年
在 AI 时代,若你还在紧盯代码量、执着于全栈工程师的招聘,或者仅凭技术贡献率来评判价值,执着于业务提效的比例而忽略产研价值,你很可能已经被所谓的“常识”困住了脚步。
677 57
大厂CIO独家分享:AI如何重塑开发者未来十年
|
8天前
|
存储 自然语言处理 测试技术
一行代码,让 Elasticsearch 集群瞬间雪崩——5000W 数据压测下的性能避坑全攻略
本文深入剖析 Elasticsearch 中模糊查询的三大陷阱及性能优化方案。通过5000 万级数据量下做了高压测试,用真实数据复刻事故现场,助力开发者规避“查询雪崩”,为您的业务保驾护航。
429 27
|
15天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
911 59
Meta SAM3开源:让图像分割,听懂你的话
|
5天前
|
弹性计算 网络协议 Linux
阿里云ECS云服务器详细新手购买流程步骤(图文详解)
新手怎么购买阿里云服务器ECS?今天出一期阿里云服务器ECS自定义购买流程:图文全解析,阿里云服务器ECS购买流程图解,自定义购买ECS的设置选项是最复杂的,以自定义购买云服务器ECS为例,包括付费类型、地域、网络及可用区、实例、镜像、系统盘、数据盘、公网IP、安全组及登录凭证详细设置教程:
200 114