C#序列化与反序列化方式简单总结
序列化和反序列化
相关类:
System.SerializableAttribute特性(或称为属性),
System.Runtime.Serialization.ISerializable(自定义序列化接口)
https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.iserializable.aspx,
System.Runtime.Serialization.IserializationSurrogate(自定义序列化代理接口),
System.Runtime.Serializatin.SurrogateSelector(自定义序列化代理设置类)
1:官方备注
序列化使用
BinaryFormatter(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx)或
SopaFormatter(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatters.soap.soapformatter.aspx),使用方法类同。
System.SerializableAttribute特性:
将SerializableAttribute特性应用于一个类型可指示该类型的实例可以序化。如果正在序列化的对象图中的任何类型未应用SerializableAttribute特性,公共语言运行时则会引发SerializableException(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.serializationexception.aspx)。
即使该类会实现ISerializable接口来控制序列化进程,仍要应用SerializableAttribute特性。
将SerializableAttribute特性应用于类型时,序列化默认情况下所有私有和公共字段。
也可以从序列化排除字段通过应用NonSerializedAttribute(https://msdn.microsoft.com/zh-cn/library/system.nonserializedattribute.aspx)特性应用于字段。如果可序列化类型的字段包含指针、句柄或其他模型针对于特定环境的数据结构,并且不能在不同的环境中以有异议的方式重建,则最好经NonSerializableAttribute特性应用于该字段。
System.Runtime.Serialization.ISerializable接口:
任何可以序列化的类都必须用SerializableAttribute进行标记。如果某个类需要控制器序列化进程,它可以实现ISerializable接口。Formatter(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.formatter.aspx)在序列化时调用GetObjectData,并使用表示对象所需的全部数据来填充所提供的SerializationInfo(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.serializationinfo.aspx)。Formatter使用图形中对象的类型来创建SerializationInfo。需要自己发送代理的对象可以使用SerializationInfo上的FullTypeName和AssemblyName属性来更改所传输的信息,或直接使用方法SetType,与同时设置FullTypeName和AssemblyName等效。
在类继承的情况下,可以序列化从实现ISerializable的基类中派生的类。这种情况下,派生的类应在GetObjectData的实现内调用GetObjectData的基类实现。否则,不会序列化来自基类的数据。
ISerializable接口需要带有签字(SerializationInfo,StreamingContext)的构造函数。在反序列化时,仅在格式化程序已反序列化SerializationInfo中的数据后才调用当前构造函数。一般而言,如果该类未密封,则应保护此构造函数,序列化过程会忽略此构造方法的访问修饰符,及应当使用protected或private(类被sealed修饰时)来修饰此构造方法。
无法保证对象被反序列化的顺序。例如,如果一种类型引用尚未反序列化的类型,则会引发异常。如果创建具有这种依赖关系的类型,可以通过IDeserializationCallback(https://msdn.microsoft.com/zh-cn/library/system.runtime.serialization.ideserializationcallback.aspx)接口和OnDeserialization方法来解决该问题。
序列化接口处理像处理扩展Object的类型一样,处理扩展MarshalByRefObject(https://msdn.microsoft.com/zh-cn/library/system.marshalbyrefobject.aspx)的对象类型。这些类型都可以使用SerializableAttribute来标记,并且可以将ISerializable接口实现为其他任何对象类型。它们的对象状态将被捕获并在流中持续。
当通过System.Runtime.Remotting使用这些类型时,远程处理接口会提供一个代理项,它将取代常用的序列化,而将代理序列化为MarshalByRefObject。代理项是知道如何将特定类型的对象序列化和反序列化的帮助器。代理在大多数情况下对用户不可见,其类型将是ObjRef(https://msdn.microsoft.com/zh-cn/library/system.runtime.remoting.objref.aspx)。
作为一种常规的设计模式,类很少既使用可序列化特性来标记,又扩展MarshalByRefObject。当组合这两项特性时,开发人员应仔细考虑可能的序列化和远程处理方案。MemoryStream就是一个适用的示例。当MemoryStream的基类从MarshalByRefObject扩展时,可以捕获MemoryStream的状态并随时将其还原。因此,这样做可能是有意义的:将该流的状态序列化到数据库中,并在稍后某一时间将其还原。但是,当通过远程处理来使用时,这种类型的对象将设置代理。
有关序列化MarshalByRefObject的派生类的更多信息,请参见RemottingSurrogateSelector(https://msdn.microsoft.com/zh-cn/library/system.runtime.remoting.messaging.remotingsurrogateselector.aspx)。
关于如果实现ISerializable的更多信息,请参见自定义序列化(https://msdn.microsoft.com/zh-cn/library/ty01x675.aspx)。
System.Runtime.Serialization.ISerializationSurrogate接口:
实现序列化代理选择器,此选择器允许一个对象对另一个对象执行序列化和反序列化。
System.Runtime.Serializatin.SurrogateSelector类:
序列化代理项将为用户提供一种对象,该对象可以处理不同对象的序列化要求,并且可以再必要时转换序列化数据。该类实现接口System.Runtime.Serializatin.ISurrogateSelector。
System.Runtime.Serializatin.ISurrogateSelector接口:
实现该接口的类可用于选择代理项,以使用该代理项的序列化和反序列方法对其他类进行序列化或序列化操作。
2:简单序列化
需要使用的类有SerializableAttribute特性,和BinaryFormatter,对于不需要或不应序列化的类成员需用NonSerializableAttribute特性修饰。
代码如下:
[Serializable]
public class MyItemType{
//其他成员…
[NonSerializable]
public string IgnorField{…}
}
//序列化过程
string fileName = “[文件名]”;
MyItemType t = new MyItemType();
FileStream fs = new FileStream(fileName,FileMode.Create);
IFromatter formatter = new BinaryFormatter();
formatter.Serialize(fs, t);
fs.Close();
//反序列化过程
string fileName = “[文件名]”;
MyItemType result = null;
FileStream fs = new FileStream(fileName, FileMode.Open);
IFormatter formatter = new BinaryFormatter();
result = formatter.Deserialize(fs);
fs.Close();
3:使用ISerializable接口实现自定义序列化
继承ISerializable接口需实现方法GetObjectData,并添加一个具有签名SerializationInfo info和StreamingContext context的构造方法以供反序列化使用,须注意的是此构造方法的访问修饰符在反序列化过程中将被忽略,因此为防止此构造方法被错误的调用应对其使用较严格的访问修饰符比如protected或private。
实现此接口的类也应当使用SerializableAttribute修饰。
代码实例:
[Serializable]
public class MyItemType:Isereializable
{
//字段….
#region 自定义序列化
private MyItemType(SerializationInfo info, StreamingContext context)
{
ThisObjectStringField = info.GetValue(“keyName”, typeof(string));
ThisObjectIntField = info.GetInt32(“keyName2”);
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(“keyName”, ThisObjectStringField, typeof(string));
//info.AddInt32(“keyName”, ThisObjectIntField);//此行错误,info没有强类型的值添加方法
}
#endregion
}
//使用方法同于简单序列化代码实例中的使用方法
4:使用IserializationSurrogate接口实现的序列化代理项
使用IserializationSurrogate实现类可对另一个类进行序列化和反序列化。
此序列化方式使用到的类或接口还包括对代理项选择的SurrogateSelector类,Iformatter实现类(此处使用BinaryFormatter)
示例代码:
//自定义序列化代理
public class Surrogate : ISerializationSurrogate
{
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
if (obj is MyItemType)
{
MyItemType temp = (MyItemType)obj;
info.AddValue("props", temp, typeof(string));
}
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
if (obj is MyItemType)
{
MyItemType temp = (MyItemType)obj;
temp.MyProperty = (string)info.GetValue("props", typeof(string));
Console.WriteLine("SetObjectData");
return temp;
}
return null;
}
//使用方法
Surrogate surrogate = new Surrogate();
SurrogateSelector selector = new SurrogateSelector();
selector.AddSurrogate(typeof(MyItemType), new StreamingContext(StreamingContextStates.All), surrogate);
formatter.SurrogateSelector = selector;
FileStream fs = new FileStream(fileName, FileMode.Open);
formatter.Deserialize(fs);
fs.Close();
//总结时间:2015-03-17
//修改时间:2015-03-23
C#序列化与反序列化方式简单总结的更多相关文章
- Java:对一个对象序列化和反序列化的简单实现
名词解释 序列化:将Java对象转化成字节的过程 反序列化:将字节转化成Java对象的过程 字节:1字节(byte)= 8bit,bit就是计算机认识的二进制 序列化的作用 Java对象是在Java虚 ...
- C#中的Json的序列化和反序列化
Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...
- 第一章 JacksonUtil 序列化与反序列化属性总结
1.json-lib与Jackson 关于json-lib与Jackson对比总结如下: 1).性能方面,Jackson的处理能力高出Json-lib10倍左右. 2).json-lib已经停止更新, ...
- 序列化、反序列化和transient关键字的作用
引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口, ...
- .Net类的序列化和反序列化 - 进阶者系列 - 学习者系列文章
今天看了下以前的一个工具的代码,其中涉及到.NET类的序列化和反序列化问题,所以就写一下. 这里说一下.NET类序列化的好处..NET类在序列化之前只是一个相对狭义的类.通过序列化,能够更好的保存该类 ...
- java梳理-序列化与反序列化
一背景: 之前笔记关于rpc框架介绍中,提到为了调用远程服务,需要再确定消息结构后考虑序列化与反序列化,序列化主要是把对象转换成二进制码便于网络传输,反序列化就是相反的,主要目的是生成对象便于后续处理 ...
- .Net中的序列化和反序列化详解
序列化通俗地讲就是将一个对象转换成一个字节流的过程,这样就可以轻松保存在磁盘文件或数据库中.反序列化是序列化的逆过程,就是将一个字节流转换回原来的对象的过程. 然而为什么需要序列化和反序列化这样的机制 ...
- 浅谈C#中的序列化与反序列化
今天我利用这篇文章给大家讲解一下C#中的序列化与反序列化.这两个概念我们再开发中经常用到,但是我们绝大部分只用到了其中的一部分,剩下的部分很多开发人员并不清楚,甚至可以说是不知道.因此我希望通过这篇文 ...
- Java 中序列化与反序列化
一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...
随机推荐
- [网络技术][转]网卡的offload概念
网络数据包分析 网卡Offload 对于网络安全来说,网络传输数据包的捕获和分析是个基础工作,绿盟科技研究员在日常工作中,经常会捕获到一些大小远大于MTU值的数据包,经过分析这些大包的特性,发现和网卡 ...
- PhantomJS linux系统下安装步骤及使用方法(网页截屏功能)
PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, ...
- Australian troops to the fight against Islamic State militants.
He arrived in Arnhem Land on Sunday, honouring an election promise to spend a week every year in an ...
- cocos2d-x WebSocket
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术.在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道 ...
- [SHELL]判断一个命令是否存在
首先要说明的是,不要使用which来进行判断,理由如下: 1.which非SHELL的内置命令,用起来比内置命令的开销大,并且非内置命令会依赖平台的实现,不同平台的实现可能不同. # type typ ...
- 随感一:android handler传值更改ui
handler+looper传值更改activity的UI 博客开了一段时间,一直想写点自己的学习经验及体会,等着以后长时间不用再要用到的时候直接拿过来上手.想了想,之前用到handler, 看了几篇 ...
- adb -s emulator-5554 install JDKCast-PAP.apk
multi-emulators direct to install app adb -s emulator-5554 install JDKCast-PAP.apk
- Ubuntu 16.04 软件中心闪退 解决方案
最近使用16.04不知道是哪里出了问题,软件中心打不开了,点击图标之后完全不显示GUI,过一会儿软件就自动关闭了,然后也没有报错的log. 虽然可以使用命令行升级,但是强迫症不能忍啊. 经过一番折腾, ...
- KinerCode.js
1 /*验证码*/ function KinerCode(options) { this.opt = this.extend(true, this.options, options); this.op ...
- Maven 标签详解
<span style="padding:0px; margin:0px"><project xmlns="http://maven.apache.or ...