详细序列化和反序列化笔记

序列化概念:

按值封送:将对象从一个应用程序域传输到另一个应用程序域,居然后反序列化,以便第二个应用程序域中生成该对象的一个精确副本。

如果对象从MarshalByRefObject派生,则将对象引用从一个应用程序域传递到另一个。

自定义序列化的安全问题:

序列化可以允许其他代码查看或修改用其他方式无法访问的对象数据。因此执行序列化的代码需要制定SerializationFormatter标识的SecurityPermission。默认情况下,网络下载的代码不会授予该权限,只有本地计算机上的代码才被授予该权限,必须采用下列方式保护GetObjectData方法:要求使用具有指定SerializationFormatter标志的SecurityPermission;或要求具备专门用于帮助保护私有数据的其他权限。

版本容错序列化VTS:

二进制序列化和Soap序列化均会启用VTS,在反序列化时,忽略所有外来或意外数据而导致的异常。OptionalFieldAttribute特性修饰字段,可将字段标记为可选,反序列化期间,因缺少数据无法对该字段进行反序列化时,此确实将会被忽略。

OptionalFieldAttribute特性的属性VersionAdded用于标记类的版本,应当在每次修改类型时,版本应该正好增加1,鉴于这一属性未在.Net Framework2.0中使用,该版本号应该从2开始。

使用SerializationBinder控制序列化和反序列化:

序列化过程中,格式化程序传输创建正确类型和版本的对象实例所需要的信息,包括对象的完整名称和程序集名称。默认情况下反序列化可使用此信息创建相同对象实例。

但由于原始类可能在执行反序列化的计算机上不存在,原始类已经在程序集之间移动或服务器与客户端要求使用不同的版本,因此用户可能需要控制序列化和反序列化的具体类。子功能只能在使用BinaryFormatter和NetDataContractSerializer时使用。

此功能需要继承抽象类SerializationBinder并重写方法BindToName和BindToType(必须重写,此方法传入的参数是被序列化的类的程序集名称和类型的完全限定名)。

序列化最佳实践:

切勿移除已序列化的字段。

如果旧版本未使用NoSerializedAttribute修饰字段,则新版本也不应该使用。

切勿修改已序列化字段的名称或类型。

如果添加新的字段,应使用OptionalFieldAttribute特性修饰。

移除NonSerializedAttribute修饰的字段应使用OptionalFieldAttribute修饰。

对于不能接受0或null作为默认值的字段,应使用序列化回调设置有意义的默认值。

如果要确保类型与将来的序列化引擎的兼容应始终使用OptionalFieldAttribute的VersionAdded属性设置版本,并避免版本分支。

C#的序列化分为二进制序列化,Soap序列化,XML序列化。

工具类:

二进制序列化将对象序列化为二进制格式,使用System.Runtime.Serialization.Formatters.Binary.BinaryFormatter类进行。

Soap序列化将对象序列化为符合SOAP协议传输的数据格式,使用System.Runtime.Serialization.Formatters.Soap.SoapFormatter类进行。

XML序列化将对象序列化为XML数据,使用System.Xml.Serialization.XmlSerializer类实现。

序列化方式的不同:

二进制序列化与Soap序列化将对象的可序列化的公共或私有字段序列化,XML序列化仅仅将公共字段或属性进行序列化。

二进制序列化会将类的完全限定名与程序集完整名称(项目名称,版本,公钥标记,区域性等)进行序列化。

Soap序列化使用XML命名空间序列化原始程序集信息。

XML序列化不保存限定名和程序集名称,但XML的反序列化仍旧无法序列化为同成员的其他的类。XML序列化需要制定序列化对象的类型。

SerializableAttribute特性相关说明:

需要持久化的类必须使用SerializableAttribute特性修饰,可选择性的使用NonSerializedAttribute特性修饰不需要序列化的属性或字段。

但在使用XML序列化时不需要SerializableAttribute特性修饰,但要求必须一个无参构造方法。

二进制序列化与Soap序列化:

另见简单序列化和反序列化笔记。

注意:Soap序列化不支持泛型。

XML序列化:

XML序列化不需要SerializableAttribute特性修饰被序列化的类,但要求必须具有无参构造函数。

XML只能序列化公开的属性或字段,被序列化的属性或字段如果没有显示使用特性修饰,则除集合属性或字段外,普通属性或字段默认使用XmlElementAttribute特性修饰。

对象中使用XmlTextAttribute修饰的属性或对象将被序列化为父元素的文本子节点而不是元素子节点。

XmlElementAttribute可用于修改被修饰的属性或字段序列化后的元素名称,该特性的属性Order可用于指定被修饰属性或字段序列化成xml元素后出现的顺序。

类使用XmlTypeAttribute修饰可用于类修改序列化后的对应的元素的名称。

类属性使用XmlAttributeAttribute特性可将属性或字段序列化为父元素的xml属性。

XmlArrayAttribute特性可修改修饰的集合成员对应的元素的名称,集合属性如果被XmlElementAttribute特性修饰,则等同于使用该特性修饰集合属性的每一个元素,例如:

public class WomanWithFriend

{

//[XmlArray("朋友们")]

//[XmlArrayItem("朋友")]

[XmlElement]

public List<Woman> Friends { get; set; }

public Woman Self { get; set; }

}

public class Woman

{

public string WomanName { get; set; }

public int Age { get; set; }

public string Description { get; set; }

}

//使用XmlElement修饰的结果:

<?xml version="1.0"?>

<WomanWithFriend xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<Friends WomanName="女人1" Age="23">这里是对雌性人类的描述</Friends>

<Friends WomanName="女人2" Age="23">这里是对雌性人类的描述</Friends>

<Friends WomanName="女人3" Age="23">这里是对雌性人类的描述</Friends>

<Self WomanName="女人自己" Age="15">这里是女人自己</Self>

</WomanWithFriend>

//不使用XmlElement使用XmlArray和XMLArrayItem修饰的结果:

<?xml version="1.0"?>

<WomanWithFriend xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<Friends>

<Woman WomanName="女人1" Age="23">这里是对雌性人类的描述</Woman>

<Woman WomanName="女人2" Age="23">这里是对雌性人类的描述</Woman>

<Woman WomanName="女人3" Age="23">这里是对雌性人类的描述</Woman>

</Friends>

<Self WomanName="女人自己" Age="15">这里是女人自己</Self>

</WomanWithFriend>

XmlArrayItemAttribute特性可修改被修饰的集合成员的元素对应的xml元素的名称,作为集合属性元素的类的XmlTypeAttribute设置的xml元素名称会被覆盖,该特性的构造函数可传递Type值,以便对集合类型的属性使用多态时(集合属性指定为基类,但集合的元素是至少一种派生类)指定集合类型的属性的元素的类型有哪些(每一个XmlArrayItemAttribute指定一种派生类,如果集合属性的元素具有多个派生类,则应使用多个XmlArrayItemAttribute特性)。

被XmlIgnoreAttribute修饰的属性或字段不会被序列化。

XmlRootAttribute修饰类可用于设置序列化的根节点的属性。

Xml序列化的自定义使用IXmlSerializable接口,通过XmlReader和XmlWriter来进行序列化和反序列化的过程,代码示例:

public class CustomerXmlSerializable : IXmlSerializable

{

public string Name;

public System.Xml.Schema.XmlSchema GetSchema()//不知晓

{

return null;

}

public void ReadXml(System.Xml.XmlReader reader)

{

Name = reader.GetAttribute("名称");

}

public void WriteXml(System.Xml.XmlWriter writer)

{

writer.WriteAttributeString("名称", Name);

}

}

//修改日期2015-09-20

时间: 2024-11-05 17:29:18

详细序列化和反序列化笔记的相关文章

.net学习笔记--序列化与反序列化

序列化其实就是将一个对象的所有相关的数据保存为一个二进制文件(注意:是一个对象) 而且与这个对象相关的所有类型都必须是可序列化的所以要在相关类中加上 [Serializable]特性 对象类型包括:对象本神包含的类型,父类 拥有需要的对象之后:1.将对象转换为二进制数据 使用专门的对像进行转换 BinaryFormatter 2.将二进制数据写入到文件 FileSteam 反序列化则是把二进制文件转换为一个对象 例子代码如下: 1 using System; 2 using System.Col

java中的序列化和反序列化学习笔记

需要序列化的Person类: package cn.itcast_07; import java.io.Serializable; /* * NotSerializableException:未序列化异常 * * 类通过实现 java.io.Serializable 接口以启用其序列化功能.未实现此接口的类将无法使其任何状态序列化或反序列化. * 该接口居然没有任何方法,类似于这种没有方法的接口被称为标记接口. * * java.io.InvalidClassException: * cn.it

对象的序列化与反序列化---IO学习笔记(四)

对象的序列化,反序列化 对象的序列化: 就是将Object转换成byte序列 对象的反序列化: 将byte序列转换成Object 序列化流.反序列化流 序列化流(ObjectOutputStream),是字节的过滤流->主要方法:writeObject() 反序列化流(ObjectInputStream)->主要方法:readObject() 序列化接口(Serializable) 对象必须实现序列化接口.才干进行序列化.否则将出现异常 这个接口,没有不论什么方法,仅仅是一个标准. 主要的对象

java中的对象的序列化与反序列化的知识点---IO学习笔记(四)

对象的序列化,反序列化 对象的序列化: 就是将Object转换成byte序列 对象的反序列化: 将byte序列转换成Object 序列化流,反序列化流 序列化流(ObjectOutputStream),是字节的过滤流->主要方法:writeObject() 反序列化流(ObjectInputStream)->主要方法:readObject() 序列化接口(Serializable) 对象必须实现序列化接口,才能进行序列化,否则将出现异常 这个接口,没有任何方法,只是一个标准. 基本的对象序列化

Python 学习笔记 - 序列化和反序列化

这一节看看在Python中如何序列化和反序列化.简单的说,序列化就是把内存中保存的数据类型转换为可以存储或者传输的过程,比如说我把一个字典转换为一个字符串这样就可以方便传递或者保存了:反序列化则是倒过来,把字符串转换为对应的数据类型. Python里面常用的有两种方式. JSON Pickle 首先来看看JSON, 例1 比如说我有一个字典如下所示: >>> import json dic={"k1":"v1"} print(dic,type(di

PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化)/约束类型/魔术方法小结

  前  言  OOP  学习了好久的PHP,今天来总结一下PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化). 1  PHP中的抽象类与抽象方法 1.什么是抽象方法?              没有方法体 {} 的方法,必须使用abstract 关键字修饰.这样的方,我们叫做抽象方法.                    abstract function say(); //    抽象方法 2.什么是抽象类?        

Python 中数据的序列化和反序列化(json处理)

概念: JSON(JavaScript Object Notation):是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集. JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等). 这些

Java对象表示方式1:序列化、反序列化和transient关键字的作用

http://www.cnblogs.com/xrq730/p/4821958.html 平时我们在Java内存中的对象,是无 法进行IO操作或者网络通信的,因为在进行IO操作或者网络通信的时候,人家根本不知道内存中的对象是个什么东西,因此必须将对象以某种方式表示出来,即 存储对象中的状态.一个Java对象的表示有各种各样的方式,Java本身也提供给了用户一种表示对象的方式,那就是序列化.换句话说,序列化只是表示对 象的一种方式而已.OK,有了序列化,那么必然有反序列化,我们先看一下序列化.反序

【Java基础】序列化与反序列化深入分析

一.前言 复习Java基础知识点的序列化与反序列化过程,整理了如下学习笔记. 二.为什么需要序列化与反序列化 程序运行时,只要需要,对象可以一直存在,并且我们可以随时访问对象的一些状态信息,如果程序终止,那么对象是肯定不会存在的,但是有时候,我们需要再程序终止时保存对象的状态信息,之后程序再次运行时可以重新恢复到之前的状态,如,玩家玩游戏退出时,需要保存玩家的状态信息(如等级.装备等等),之后玩家再此登入时,必须要恢复这些状态信息.我们可以通过数据库手段来达到这个保存状态的目的,在Java中,我