C# 序列化理解 1(转)
序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。
.NET框架提供了两种串行化的方式:1、是使用BinaryFormatter进行串行化;2、使用SoapFormatter进行串行化;3、使用XmlSerializer进行串行化。第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储;第三种其实和第二种差不多也是XML的格式存储,只不过比第二种的XML格式要简化很多(去掉了SOAP特有的额外信息)。
可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、2可以使用[NonSerialized]属性来标志,2、可以使用[XmlIgnore]来标志。
1、使用BinaryFormatter进行串行化
下面是一个可串行化的类:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
/// <summary>
/// ClassToSerialize 的摘要说明
/// </summary>
[Serializable]
public class ClassToSerialize
{
public int id = 100;
public string name = "Name";
[NonSerialized]
public string Sex = "男";
}
下面是串行化和反串行化的方法:
{
ClassToSerialize c = new ClassToSerialize();
FileStream fileStream = new FileStream("c:\\temp.dat", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(fileStream, c);
fileStream.Close();
}
public void DeSerializeNow()
{
ClassToSerialize c = new ClassToSerialize();
c.Sex = "kkkk";
FileStream fileStream = new FileStream("c:\\temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryFormatter b = new BinaryFormatter();
c = b.Deserialize(fileStream) as ClassToSerialize;
Response.Write(c.name);
Response.Write(c.Sex);
fileStream.Close();
}
调用上述两个方法就可以看到串行化的结果:Sex属性因为被标志为[NonSerialized],故其值总是为null。
2、使用SoapFormatter进行串行化
和BinaryFormatter类似,我们只需要做一下简单修改即可:
a.将using语句中的.Formatter.Binary改为.Formatter.Soap;
b.将所有的BinaryFormatter替换为SoapFormatter.
c.确保报存文件的扩展名为.xml
经过上面简单改动,即可实现SoapFormatter的串行化,这时候产生的文件就是一个xml格式的文件。
3、使用XmlSerializer进行串行化
关于格式化器还有一个问题,假设我们需要XML,但是不想要SOAP特有的额外信息,那么我们应该怎么办呢?有两中方案:要么编写一个实现IFormatter接口的类,采用的方式类似于SoapFormatter类,但是没有你不需要的信息;要么使用库类XmlSerializer,这个类不使用Serializable属性,但是它提供了类似的功能。
如果我们不想使用主流的串行化机制,而想使用XmlSeralizer进行串行化我们需要做一下修改:
a.添加System.Xml.Serialization命名空间。
b.Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的行为与NoSerialized类似。
c.XmlSeralizer要求类有个默认的构造器,这个条件可能已经满足了。
下面看示例:
要序列化的类:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Serialization;
[Serializable]
public class Person
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public string Sex;
public int Age = 31;
public Course[] Courses;
public Person()
{
}
public Person(string Name)
{
name = Name;
Sex = "男";
}
}
[Serializable]
public class Course
{
public string Name;
[XmlIgnore]
public string Description;
public Course()
{
}
public Course(string name, string description)
{
Name = name;
Description = description;
}
}
序列化和反序列化方法:
{
Person c = new Person("cyj");
c.Courses = new Course[2];
c.Courses[0] = new Course("英语", "交流工具");
c.Courses[1] = new Course("数学","自然科学");
XmlSerializer xs = new XmlSerializer(typeof(Person));
Stream stream = new FileStream("c:\\cyj.XML",FileMode.Create,FileAccess.Write,FileShare.Read);
xs.Serialize(stream,c);
stream.Close();
}
public void XMLDeserialize()
{
XmlSerializer xs = new XmlSerializer(typeof(Person));
Stream stream = new FileStream("C:\\cyj.XML",FileMode.Open,FileAccess.Read,FileShare.Read);
Person p = xs.Deserialize(stream) as Person;
Response.Write(p.Name);
Response.Write(p.Age.ToString());
Response.Write(p.Courses[0].Name);
Response.Write(p.Courses[0].Description);
Response.Write(p.Courses[1].Name);
Response.Write(p.Courses[1].Description);
stream.Close();
}
这里Course类的Description属性值将始终为null,生成的xml文档中也没有该节点,如下图:
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Sex>男</Sex>
<Age>31</Age>
<Courses>
<Course>
<Name>英语</Name>
<Description>交流工具</Description>
</Course>
<Course>
<Name>数学</Name>
<Description>自然科学</Description>
</Course>
</Courses>
<Name>cyj</Name>
</Person>
4、自定义序列化
如果你希望让用户对类进行串行化,但是对数据流的组织方式不完全满意,那么可以通过在自定义类中实现接口来自定义串行化行为。这个接口只有一个方法,GetObjectData. 这个方法用于将对类对象进行串行化所需要的数据填进SerializationInfo对象。你使用的格式化器将构造SerializationInfo对象,然后在串行化时调用GetObjectData. 如果类的父类也实现了ISerializable,那么应该调用GetObjectData的父类实现。
如果你实现了ISerializable,那么还必须提供一个具有特定原型的构造器,这个构造器的参数列表必须与GetObjectData相同。这个构造器应该被声明为私有的或受保护的,以防止粗心的开发人员直接使用它。
示例如下:
实现ISerializable的类:
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
/// <summary>
/// Employee 的摘要说明
/// </summary>
[Serializable]
public class Employee:ISerializable
{
public int EmpId=100;
public string EmpName="刘德华";
[NonSerialized]
public string NoSerialString = "NoSerialString-Test";
public Employee()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
private Employee(SerializationInfo info, StreamingContext ctxt)
{
EmpId = (int)info.GetValue("EmployeeId", typeof(int));
EmpName = (String)info.GetValue("EmployeeName",typeof(string));
//NoSerialString = (String)info.GetValue("EmployeeString",typeof(string));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("EmployeeId", EmpId);
info.AddValue("EmployeeName", EmpName);
//info.AddValue("EmployeeString", NoSerialString);
}
}
序列化和反序列化方法:
{
Employee mp = new Employee();
mp.EmpId = 10;
mp.EmpName = "邱枫";
mp.NoSerialString = "你好呀";
Stream steam = File.Open("c:\\temp3.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
Response.Write("Writing Employee Info:");
bf.Serialize(steam,mp);
steam.Close();
mp = null;
//反序列化
Stream steam2 = File.Open("c:\\temp3.dat", FileMode.Open);
BinaryFormatter bf2 = new BinaryFormatter();
Response.Write("Reading Employee Info:");
Employee mp2 = (Employee)bf2.Deserialize(steam2);
steam2.Close();
Response.Write(mp2.EmpId);
Response.Write(mp2.EmpName);
Response.Write(mp2.NoSerialString);
}
C# 序列化理解 1(转)的更多相关文章
- C# 序列化理解 2(转)
一.概述 序列化是把对象转变成流.相反的过程就是反序列化. 哪些场合用到这项技术呢? 1. 把对象保存到本地,下次运行程序时恢复这个对象. 2. 把对象传送到网络的另一台终端上,然后在此终端还原这个对 ...
- 什么是Java序列化?如何实现序列化?
一.什么是序列化: 序列化理解成“打碎”是可以的,不过在书本上的名词就是将对象转换成二进制. 二.在java中如何实现序列化: 首先我们要把准备要序列化类,实现 Serializabel接口 例如:我 ...
- JAVA 中进行网络通信时,通信的程序两端要传输的对象,不仅要序列化,而且这个对象所属的类的名字要完全一样,连包的名字都得一样
如上图项目目录,这是一个简易的QQ,客户端登录的时候要传输用户信息到服务器验证,所以两端都会用到User类的对象,但一开始我在Server端的包名是com.qq.server.common,两端的报名 ...
- Java基础知识总结--反射
反射:在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识.这个信息跟踪着每一个对象所属的类.虚拟机利用运行时类型信息选择相应的方法执行. Java反射机制是在系统运行状态 ...
- 05.DRF-Django REST framework 简介
一.明确REST接口开发的核心任务 分析一下上节的案例,可以发现,在开发REST API接口时,视图中做的最主要有三件事: 将请求的数据(如JSON格式)转换为模型类对象 操作数据库 将模型类对象转换 ...
- java 的持久化和序列化的简单理解
1.对象的持久化(Persistence) 对象持久化就是让对象的生存期超越使用对象的程序的运行期.将对象存储在可持久保存的存储介质上,在实际应用中,运用相应的对象持久化框架,将业务数据以对象的方式保 ...
- 对Java Serializable(序列化)的理解和总结
我对Java Serializable(序列化)的理解和总结 博客分类: Java技术 JavaOSSocketCC++ 1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状 ...
- 理解Java对象序列化(二)
关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...
- Java Serializable(序列化)的理解和总结、具体实现过程(转)
原文地址:http://www.apkbus.com/forum.php?mod=viewthread&tid=13576&fromuid=3402 Java Serializable ...
随机推荐
- php杂记——1(基础知识与文件读写)
1.变量前面需要加美元符号"$",常量则不需要: define('PRICE',100); echo PRICE; 2.用一个变量的值作为另一个变量的名称可以得到类似C中的指针变量 ...
- 如何在Centos7下升级Apache至最新版本
Apache是使用最广泛的应用部署软件.并且它也是所有服务器的必要组成部分.安装最新版本的apache意味着拥有更多最新的功能和修复了已知的BUG. 介绍 在这篇教程里面,我将会介绍在Centos7下 ...
- Win10启动不了的问题处理记录
前几天电脑突然出现蓝屏的情况,而且使用Win10自带的修复功能根本没有卵用,修复不了,很郁闷,死活进不了系统了,说什么“INACCESSABE BOOT DEVICE”,好像是引导设备不可用. 到网上 ...
- c++返回引用
#include <iostream> #include <ctime> using namespace std; double vals[] = {10.1, 12.6, 3 ...
- 30分钟 带你浅入requirejs源码
因为最近项目想现实一个单页功能,用的是react ,然后看了一下react route,挖槽 gzip后16k? 然后我简单写了一个纯单页(不支持多页的单页,所有入口都经过rewrite跑到index ...
- Leetcode代码补全——二叉树
在刷leetcode的过程中发现,在原网页输入答案是不需要自己构筑树和链表的,虽然便于直接思考算法,但是久而久之类似过于依赖编辑器,反而不知道如何创建树和链表,因此总结了该网页省略的部分,以其中题为例 ...
- spring-boot分页插件
1.分页插件,spring-boot.,第一次调用时,存值到 model.addAttribute("status", id);页面获取2.页面获取 后台存入的值,放在input ...
- 剑指offer-数值的整数次方12
class Solution: def Power(self, base, exponent): # write code here if base==0: return 0 if exponent= ...
- 局部敏感哈希LSH
之前介绍了Annoy,Annoy是一种高维空间寻找近似最近邻的算法(ANN)的一种,接下来再讨论一种ANN算法,LSH局部敏感哈希. LSH的基本思想是: 原始空间中相邻的数据点通过映射或投影变换后, ...
- ThinkPHP5项目目录规划实践
ThinkPHP5安装后(或者下载后的压缩文件解压后)可以看到下面的目录结构: tp5├─application 应用目录 ├─extend 扩展类库目录(可定义) ├─pu ...