有关.NET中序列化的一些知识
“序列化”可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后“反序列化”该对象时,创建原始对象的精确复本。
一、为什么要选择序列化
一个原因是将对象的状态保持在存储媒体中,以便可以在以后重新创建精确的副本;
另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中。
例如,序列化可用于在 ASP.NET 中保存会话状态并将对象复制到 Windows 窗体的剪贴板中。远程处理还可以使用序列化通过值将对象从一个应用程序域传递到另一个应用程序域中。
二、如何实现对象的序列化及反序列化
要实现对象的序列化,首先要保证该对象可以序列化。而且,序列化只是将对象的属性进行有效的保存,对于对象的一些方法则无法实现序列化的。
实现一个类可序列化的最简便的方法就是增加Serializable属性标记类。如:
[Serializable()]
public class MEABlock
{
private int m_ID;
public string Caption;
public MEABlock()
{
///构造函数
}
}
即可实现该类的可序列化。
要将该类的实例序列化为到文件中?.NET FrameWork提供了两种方法:
1、XML序列化
使用 XmLSerializer 类,可将下列项序列化。
MEABlock myBlock = new MEABlock();
// Insert code to set properties and fields of the object.
XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
// To write to a file, create a StreamWriter object.
StreamWriter myWriter = new StreamWriter("myFileName.xml");
mySerializer.Serialize(myWriter, MEABlock);
需要注意的是XML序列化只会将public的字段保存,对于私有字段不予于保存。
生成的XML文件格式如下:
<MEABlock>
<Caption>Test</Caption>
</MEABlock>
对于对象的反序列化,则如下:
MEABlock myBlock;
// Constructs an instance of the XmlSerializer with the type
// of object that is being deserialized.
XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
// To read the file, creates a FileStream.
FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open);
// Calls the Deserialize method and casts to the object type.
myBlock = (MEABlock)mySerializer.Deserialize(myFileStream)
2、二进制序列化
与XML序列化不同的是,二进制序列化可以将类的实例中所有字段(包括私有和公有)都进行序列化操作。这就更方便、更准确的还原了对象的副本。
要实现上述类的实例的序列化,可参照如下例子:
MEABlock myBlock = new MEABlock();
// Insert code to set properties and fields of the object.
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin",FileMode.Create,FileAccess.Write, FileShare.None);
formatter.Serialize(stream, myBlock);
stream.Close();
对于对象的反序列化,则如下:
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open,FileAccess.Read, FileShare.Read);
MEABlock myBlock = (MEABlock) formatter.Deserialize(stream);
stream.Close();
三、如何变相实现自定义可视化控件的序列化、反序列化
对于WinForm中自定义控件,由于继承于System.Windows.Form类,而Form类又是从MarshalByRefObject继承的,窗体本身无法做到序列化,窗体的实现基于Win32下GUI资源,不能脱离当前上下文存在。
当然可以采用变通的方法实现控件的序列化。这里采用的是记忆类模型。
定义记忆类(其实就是一个可序列化的实体类)用于记录控件的有效属性,需要序列化控件的时候,只需要将该控件的实例Copy到记忆类,演变成序列化保存该记忆类的操作。
反序列化是一个逆过程。将数据流反序列化成为该记忆类,再根据该记忆类的属性生成控件实例。而对于控件的一些事件、方法则可以继续使用。
.NET Framework 开发员指南
序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。XML 序列化仅将对象的公共字段和属性值序列化为 XML 流。XML 序列化不包括类型信息。例如,如果您有一个存在于 Library 命名空间中的 Book 对象,将不能保证它将会被反序列化为同一类型的对象。
注意 XML 序列化不转换方法、索引器、私有字段或只读属性(只读集合除外)。若要序列化对象的所有字段和属性(公共的和私有的),请使用 BinaryFormatter,而不要使用 XML 序列化。XML 序列化中最主要的类是 XmlSerializer 类,它的最重要的方法是 Serialize 和 Deserialize 方法。XmlSerializer 生成的 XML 流符合万维网联合会 (www.w3.org) XML 架构定义语言 (XSD) 1.0 的建议。另外,生成的数据类型符合标题为“XML Schema Part 2: Datatypes”(XML 架构第二部分:数据类型)的文档。
对象中的数据是用编程语言构造(如类、字段、属性、基元类型、数组,甚至 XmlElement 或 XmlAttribute 对象形式的嵌入 XML)来描述的。您可以创建自己的用属性批注的类,或者使用 XML 架构定义工具生成基于现有 XML 架构的类。
如果您有 XML 架构,就可运行 XML 架构定义工具生成一组强类型化为架构并用属性批注的类。当序列化这样的类的实例时,生成的 XML 符合 XML 架构。使用这样的类,就可针对容易操作的对象模型进行编程,同时确保生成的 XML 符合 XML 架构。这是使用 .NET Framework 中的其他类(如 XmlReader 和 XmlWriter 类)分析和写 XML 流的一种替换方法。(有关使用这些类的更多信息,请参见使用 .NET Framework 中的 XML。)这些类使您可以分析任何 XML 流。与此相反,当需要 XML 流符合已知的 XML 架构时,请使用 XmlSerializer。
属性控制由 XmlSerializer 类生成的 XML 流,使您可以设置 XML 流的 XML 命名空间、元素名、属性名等。有关这些属性和它们如何控制 XML 序列化的更多信息,请参见使用属性控制 XML 序列化。若想获得一个列示对所生成的 XML 起控制作用的那些属性的表,请参见控制 XML 序列化的属性。
XmlSerializer 类可进一步序列化对象并生成编码的 SOAP XML 流。生成的 XML 符合标题为“Simple Object Access Protocol (SOAP) 1.1”的万维网联合会文档的第 5 节。有关此过程的更多信息,请参见用 XML 序列化生成 SOAP 消息。有关控制生成的 XML 的属性表,请参见控制编码的 SOAP 序列化的属性。
XmlSerializer 类生成由 XML Web services 创建和传递给 XML Web services 的 SOAP 消息。若要控制 SOAP 消息,可将属性应用于 XML Web services 文件 (.asmx) 中的类、返回值、参数和字段。您可以同时使用在“控制 XML 序列化的属性”中列出的属性和在“控制编码的 SOAP 序列化的属性”中列出的属性,因为 XML Web services 可以使用文本样式,也可以使用编码的 SOAP 样式。有关使用属性控制 XML Web services 所生成的 XML 的更多信息,请参见 XML Web services 的 XML 序列化。有关 SOAP 和 XML Web services 的更多信息,请参见自定义 SOAP 消息。
保护 XmlSerializer 应用程序在创建使用 XmlSerializer 的应用程序时,您应当了解以下几点以及它们的影响:
[Visual Basic]Public Class OrderForm Public OrderDate As DateTimeEnd Class[C#]public class OrderForm{ public DateTime OrderDate;}
当将此类的实例序列化时,该实例可能类似于下面的代码:
<OrderForm> <OrderDate>12/12/01</OrderDate></OrderForm>
有关序列化的更多示例,请参见 XML 序列化的示例。
可以序列化的项使用 XmLSerializer 类,可将下列项序列化。
序列化对象
使用 XML 序列化的好处XmlSerializer 类在您将对象序列化为 XML 时为您提供完整而灵活的控制。如果您正在创建 XML Web services,则可以将控制序列化的属性应用于类和成员以确保 XML 输出符合特定的架构。
例如,XmlSerializer 使您能够:
XML 序列化注意事项使用 XmlSerializer 类时,应考虑下列情况:
[Visual Basic]<XmlElement(DataType:="NMTOKEN")>Public MyToken As String[C#][XmlElement(DataType = "NMTOKEN")]public string MyToken;
与此类似,如果创建一个必须符合特定 XML 架构 (XSD) 的类,应当应用适当的特性并将它的 DataType 属性设置为所需的 XML 数据类型名称。
有关类型映射的完整列表,请参见下列任意一个特性类的 DataType 属性:SoapAttributeAttribute、SoapElementAttribute、XmlArrayItemAttribute、XmlAttributeAttribute、XmlElementAttribute 或 XmlRootAttribute