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

简介:

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

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

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

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

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

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

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

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

Serializable特性

 
  1. using System.Runtime.InteropServices;  
  2.  
  3. namespace System  
  4. {  
  5.     // 摘要:  
  6.     //     指示一个类可以序列化。无法继承此类。  
  7.     [ComVisible(true)]  
  8.     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]  
  9.     public sealed class SerializableAttribute : Attribute  
  10.     {  
  11.         // 摘要:  
  12.         //     初始化 System.SerializableAttribute 类的新实例。  
  13.         public SerializableAttribute();  
  14.     }  

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

IFormatter格式器接口

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

图1:

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

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

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Runtime.Serialization;  
  5.  
  6. namespace ConsoleApplication1.序列化和持久化  
  7. {  
  8.     [Serializable]  
  9.     public class MyClass   
  10.     {  
  11.         public MyClass() { }  
  12.         public string number = "MyClass状态";  
  13.     }  

二进制序列化:

 
  1. IFormatter formatter = new BinaryFormatter();  
  2. Stream stream = new FileStream("obj.bin", FileMode.Create, FileAccess.Write);  
  3. using (stream)  
  4. {  
  5.     formatter.Serialize(stream, new MyClass());  
  6. }  
  7. //反序列化  
  8. Stream stream1 = new FileStream("obj.bin", FileMode.Open, FileAccess.Read);  
  9. using (stream1)  
  10. {  
  11.     MyClass mycalss = formatter.Deserialize(stream1) as MyClass;  

SOAP序列化:

 
  1. IFormatter formatter = new SoapFormatter();  
  2.  
  3.             Stream stream = new FileStream("obj.xml", FileMode.Create, FileAccess.Write);  
  4.             using (stream)  
  5.             {  
  6.                 MyClass myclass = new MyClass();  
  7.  
  8.                 formatter.Serialize(stream, myclass);  
  9.             }  
  10.  
  11.             Stream stream1 = new FileStream("obj.xml", FileMode.Open, FileAccess.Read);  
  12.             using (stream1)  
  13.             {  
  14.                 MyClass myclass = formatter.Deserialize(stream1) as MyClass;  
  15.             } 

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

使用NonSerialized禁止成员序列化

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

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.  
  5. namespace ConsoleApplication1.序列化和持久化  
  6. {  
  7.     public class MyChildClass  
  8.     {  
  9.         public string name = "MyChildClass状态";  
  10.     }  
  11. }  

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

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Runtime.Serialization;  
  5.  
  6. namespace ConsoleApplication1.序列化和持久化  
  7. {  
  8.     [Serializable]  
  9.     public class MyClass   
  10.     {  
  11.         public string number = "MyClass状态";  
  12.  
  13.         public MyChildClass ChildClass;  
  14.  
  15.     }  
  16. }  

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

图2:

这里就报错了。

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

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Runtime.Serialization;  
  5.  
  6. namespace ConsoleApplication1.序列化和持久化  
  7. {  
  8.     [Serializable]  
  9.     public class MyClass   
  10.     {  
  11.         public string number = "MyClass状态";  
  12.  
  13.         [NonSerialized]  
  14.         public MyChildClass ChildClass;  
  15.  
  16.     }  
  17. }  

图3:

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

 

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








 本文转自 王清培 51CTO博客,原文链接:http://blog.51cto.com/wangqingpei557/657956,如需转载请自行联系原作者

相关文章
|
2月前
|
前端开发 C# 数据库
.NET中使用BootstrapBlazor组件库Table实操篇
.NET中使用BootstrapBlazor组件库Table实操篇
104 0
|
2月前
|
开发框架 前端开发 .NET
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
|
2月前
|
搜索推荐 API C#
.NET开源快速、强大、免费的电子表格组件
.NET开源快速、强大、免费的电子表格组件
|
7天前
|
存储 对象存储 Python
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
|
1月前
|
NoSQL 大数据 Redis
分享5款.NET开源免费的Redis客户端组件库
分享5款.NET开源免费的Redis客户端组件库
|
2月前
|
Java iOS开发
iOS的数据序列化(又称持久化)的两类使用方式
iOS的数据序列化(又称持久化)的两类使用方式
31 0
|
2月前
|
SQL 开发框架 JavaScript
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
54 0
|
2月前
|
SQL 开发框架 .NET
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
92 0
|
19天前
|
存储 Java
JaveSE—IO流详解:对象输入输出流(序列化及反序列化)
JaveSE—IO流详解:对象输入输出流(序列化及反序列化)
|
23天前
|
JSON Java API
jackson序列化和反序列化中的注解和扩展点大全【收藏】
jackson序列化和反序列化中的注解和扩展点大全【收藏】