序列化和反序列化

相关类:

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#序列化与反序列化方式简单总结的更多相关文章

  1. Java:对一个对象序列化和反序列化的简单实现

    名词解释 序列化:将Java对象转化成字节的过程 反序列化:将字节转化成Java对象的过程 字节:1字节(byte)= 8bit,bit就是计算机认识的二进制 序列化的作用 Java对象是在Java虚 ...

  2. C#中的Json的序列化和反序列化

    Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...

  3. 第一章 JacksonUtil 序列化与反序列化属性总结

    1.json-lib与Jackson 关于json-lib与Jackson对比总结如下: 1).性能方面,Jackson的处理能力高出Json-lib10倍左右. 2).json-lib已经停止更新, ...

  4. 序列化、反序列化和transient关键字的作用

    引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java 系列技术中一个较为重要的技术点,在大部分情况下,开发人员只需要了解被序列化的类需要实现 Serializable 接口, ...

  5. .Net类的序列化和反序列化 - 进阶者系列 - 学习者系列文章

    今天看了下以前的一个工具的代码,其中涉及到.NET类的序列化和反序列化问题,所以就写一下. 这里说一下.NET类序列化的好处..NET类在序列化之前只是一个相对狭义的类.通过序列化,能够更好的保存该类 ...

  6. java梳理-序列化与反序列化

    一背景: 之前笔记关于rpc框架介绍中,提到为了调用远程服务,需要再确定消息结构后考虑序列化与反序列化,序列化主要是把对象转换成二进制码便于网络传输,反序列化就是相反的,主要目的是生成对象便于后续处理 ...

  7. .Net中的序列化和反序列化详解

    序列化通俗地讲就是将一个对象转换成一个字节流的过程,这样就可以轻松保存在磁盘文件或数据库中.反序列化是序列化的逆过程,就是将一个字节流转换回原来的对象的过程. 然而为什么需要序列化和反序列化这样的机制 ...

  8. 浅谈C#中的序列化与反序列化

    今天我利用这篇文章给大家讲解一下C#中的序列化与反序列化.这两个概念我们再开发中经常用到,但是我们绝大部分只用到了其中的一部分,剩下的部分很多开发人员并不清楚,甚至可以说是不知道.因此我希望通过这篇文 ...

  9. Java 中序列化与反序列化

    一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...

随机推荐

  1. ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务解决

    先看oracle的监听和oracle的服务是否都启动了. 启动oracle监听:cmd命令行窗口下,输入lsnrctl start,回车即启动监听. 查看oracle的sid叫什么,比如创建数据库的时 ...

  2. C# 判断文件有没占用

    C# 判断文件有没占用 using System; using System.Collections.Generic; using System.Text; using System.Runtime. ...

  3. HTML5 <video> - 使用 DOM 进行控制

    HTML5 <video> 元素同样拥有方法.属性和事件. 其中的方法用于播放.暂停以及加载等.其中的属性(比如时长.音量等)可以被读取或设置.其中的 DOM 事件能够通知您,比方说,&l ...

  4. 上架到AppStore?第一次上架之路

    首先,用自己的Developer账户(个人付费),登陆Developer的Acount(注册证书到电脑上这一步以前就做过了,虽然忘了,但是百度上有教程,以后要注册再补-!) 打开证书管理Certifi ...

  5. 最小系统加载工具 systemjs

    systemjs 是一个最小系统加载工具,用来创建插件来处理可替代的场景加载过程,包括加载 CSS 场景和图片,主要运行在浏览器和 NodeJS 中.它是 ES6 浏览器加载程序的的扩展,将应用在本地 ...

  6. Java并发编程学习笔记(二)——对象的共享

    主要概念:可见性.重排序.失效数据.最低安全性.发布.逸出.线程封闭(Ad-hoc.栈封闭.ThreadLocal类).不变性.Final域.事实不可变对象. 1.在没有同步的情况下,编译器.处理器以 ...

  7. 错误笔记:Caused by: java.lang.StackOverflowError

    今天在将一个map转化成json出现堆栈异常,排查原因如下:出现循环递归( rootMap.put("rootMap", rootMap);),栈内存肯定耗光 代码: /** * ...

  8. (转载)android炫酷实用的开源框架(UI框架)

    可以实现一些场常用炫酷效果,包含android-lockpattern(图案密码解锁).Titanic(可以显示水位上升下降的TextView).Pull-to-Refresh.Rentals-And ...

  9. HDU 5869 (离线+树状数组)

    Problem Different GCD Subarray Query 题目大意 给定n个数的序列,有q个询问,每次询问一个区间中所有子区间所形成不同的gcd的数量. 解题分析 由于固定一个数为右端 ...

  10. MySQL的左连接、右连接和全连接的实现

    表student:+----+-----------+------+| id | name | age |+----+-----------+------+| 1 | Jim | 18 || 2 | ...