c#net实体类序列化方法_第1页
c#net实体类序列化方法_第2页
c#net实体类序列化方法_第3页
c#net实体类序列化方法_第4页
c#net实体类序列化方法_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

c#.net实体类序列化方法2011-06-0115:45佚名互联网我要评论(0)字号:T|工,收藏序列化是将对象状态转换为可保持或传输的格式的过程,在序列化过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。与序列化相对的是反序列化,它将流转换为对象。本文主要介绍实体类序列化,一起来看。AD:提到为了传递数据,需要把作为载体的实体类序列化,好好的找了一些序列化方面的介绍。感觉下面的这个介绍比较容易介绍!什么是序列化序列化是将对象状态转换为可保持或传输的格式的过程,在序列化过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。为什么使用序列化一个原因是将对象的状态保持在存储媒体中,以便可以在以后重新创建精确的副本。我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。另一个原因是通过值将对象从一个应用程序域发送到另一个应用程序域中。例如,序列化可用于在ASP.NET中保存会话状态并将对象复制到Windows窗体的剪贴板中。远程处理还可以使用序列化通过值将对象从一个应用程序域传递到另一个应用程序域中。公共语言运行时(CLR)管理对象在内存中的分布,.NET框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为Serializable(请参阅基本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。如何实现对象的序列化及反序列化要实现对象的序列化,首先要保证该对象可以序列化。而且,序列化只是将对象的属性进行有效的保存,对于对象的一些方法则无法实现序列化的。实现一个类可序列化的最简便的方法就是增加Serializable属性标记类。如:[Serializable()]publicclassMEABlockTOC\o"1-5"\h\z{privateintm_ID;publicstringCaption;publicMEABlock(){///构造函数}}即可实现该类的可序列化。注意序列化的类必须为Public,否则不能够被序列化。要将该类的实例序列化为到文件中?.NETFramework提供了两种方法:a.XML序列化使用XmLSerializer类,可将下列项序列化。公共类的公共读/写属性和字段实现ICollection或IEnumerable的类。(注意只有集合会被序列化,而公共属性却不会。)XmlElement对象。XmlNode对象。DataSet对象。要实现上述类的实例的序列化,可参照如下例子:MEABlockmyBlock=newMEABlock();//Insertcodetosetpropertiesandfieldsoftheobject.XmlSerializermySerializer=newXmlSerializer(typeof(MEABlock));//Towritetoafile,createaStreamWriterobject.StreamWritermyWriter=newStreamWriter("myFileName.xml");mySerializer.Serialize(myWriter,MEABlock);需要注意的是XML序列化只会将public的字段保存,对于私有字段不予于保存。生成的XML文件格式如下:<MEABlock><Caption>Test</Caption></MEABlock>对于对象的反序列化,则如下:MEABlockmyBlock;//ConstructsaninstanceoftheXmlSerializerwiththetype//ofobjectthatisbeingdeserialized.XmlSerializermySerializer=newXmlSerializer(typeof(MEABlock));//Toreadthefile,createsaFileStream.FileStreammyFileStream=newFileStream("myFileName.xml",FileMode.Open);//CallstheDeserializemethodandcaststotheobjecttype.myBlock=(MEABlock)mySerializer.Deserialize(myFileStream)b.二进制序列化与XML序列化不同的是,二进制序列化可以将类的实例中所有字段(包括私有和公有)都进行序列化操作。这就更方便、更准确的还原了对象的副本。要实现上述类的实例的序列化,可参照如下例子:MEABlockmyBlock=newMEABlock();//Insertcodetosetpropertiesandfieldsoftheobject.IFormatterformatter=newBinaryFormatter();Streamstream=newFileStream("MyFile.bin",FileMode.Create,FileAccess.Write,FileShare.None);formatter.Serialize(stream,myBlock);stream.Close();对于对象的反序列化,则如下:IFormatterformatter=newBinaryFormatter();Streamstream=newFileStream("MyFile.bin",FileMode.Open,FileAccess.Read,FileShare.Read);MEABlockmyBlock=(MEABlock)formatter.Deserialize(stream);stream.Close();4、如何变相实现自定义可视化控件的序列化、反序列化对于WinForm中自定义控件,由于继承于System.Windows.Form类,而Form类又是从MarshalByRefObject继承的,窗体本身无法做到序列化,窗体的实现基于Win32下GUI资源,不能脱离当前上下文存在。当然可以采用变通的方法实现控件的序列化。这里采用的是记忆类模型。定义记忆类(其实就是一个可序列化的实体类)用于记录控件的有效属性,需要序列化控件的时候,只需要将该控件的实例Copy到记忆类,演变成序列化保存该记忆类的操作。反序列化是一个逆过程。将数据流反序列化成为该记忆类,再根据该记忆类的属性生成控件实例。而对于控件的一些事件、方法则可以继续使用。wwf之所以强调要把类实例化,就是因为工作流和应用程序是在不同的线程中。二者之间需要用类作为传递数据的载体的话,就需要把该类定义为public序列化为二进制。对象的序列化和反序列化2011-06-0115:05阿蜜果博客园我要评论(0)字号:T|T收藏把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。本文主要介绍对象的序列化和反序列化,希望对你有帮助,一起来看。AD:当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。把Java对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。对象的序列化主要有两种用途:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;在网络上传送对象的字节序列。JDK类库中的序列化APIjava.io.ObjectOutputStream代表对象输出流,它的writeObject(Objectobj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式。对象序列化包括如下步骤:创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;通过对象输出流的writeObject()方法写对象。对象反序列化的步骤如下:创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;通过对象输入流的readObject()方法读取对象。下面让我们来看一个对应的例子,类的内容如下:importjava.io.*;importjava.util.Date;/***对象的序列化和反序列化测试类.*@author<ahref="mailto:xiexingxing1121@126.com">AmigoXie</a>

*@version1.0*Creationdate:2007-9-15-下午21:45:48*/publicclassObjectSaver{/**11.*@paramargs12.13.@author<ahref="mailto:xiexingxing1121@126.com">AmigoXie</a>Creationdate:2007-9-15-下午21:45:3714.*/15.publicstaticvoidmain(String[]args)throwsException{16.ObjectOutputStreamout=newObjectOutputStream17.18.(newFileOutputStream("D:""objectFile.obj"));//序列化对象19.Customercustomer=newCustomer(11.*@paramargs12.13.@author<ahref="mailto:xiexingxing1121@126.com">AmigoXie</a>Creationdate:2007-9-15-下午21:45:3714.*/15.publicstaticvoidmain(String[]args)throwsException{16.ObjectOutputStreamout=newObjectOutputStream17.18.(newFileOutputStream("D:""objectFile.obj"));//序列化对象19.Customercustomer=newCustomer("阿蜜果",24);20.out.writeObject("你好!");21.out.writeObject(newDate());22.23.out.writeObject(customer);out.writeInt(123);//写入基本类型数据24.25.out.close();//反序列化对象26.ObjectInputStreamin=newObjectInputStream27.(newFileInputStream("D:""objectFile.obj"));28.System.out.println("obj1="+(String)in.readObject());29.System.out.println("obj2="+(Date)in.readObject());30.Customerobj3=(Customer)in.readObject();31.32.System.out.println("obj3="intobj4=in.readInt();+obj3);33.System.out.println("obj4="+obj4);34.in.close();35.36.37.classCustomerimplementsSerializable{37.privateStringname;privateintage;publicCustomer(Stringname,intage){=name;this.age=age;}publicStringtoString(){age="+age;return"name="+name+age="+age;}}输出结果如下:obj1=你好!obj2=SatSep1522:02:21CST2007obj3=name=阿蜜果,age=24obj4=123因此例比较简单,在此不再详述。实现Serializable接口ObjectOutputStream只能对Serializable接口的类的对象进行序列化。默认情况下,ObjectOutputStream按照默认方式序列化,这种序列化方式仅仅对对象的非transient的实例变量进行序列化,而不会序列化对象的transient的实例变量,也不会序列化静态变量。当ObjectOutputStream按照默认方式反序列化时,具有如下特点:如果在内存中对象所属的类还没有被加载,那么会先加载并初始化这个类。如果在classpath中不存在相应的类文件,那么会抛出ClassNotFoundException;在反序列化时不会调用类的任何构造方法。如果用户希望控制类的序列化方式,可以在可序列化类中提供以下形式的writeObject()和readObject()方法。privatevoidwriteObject(java.io.ObjectOutputStreamout)throwsIOExceptionprivatevoidreadObject(java.io.ObjectInputStreamin)throwsIOException,ClassNotFoundException;当ObjectOutputStream对一个Customer对象进行序列化时,如果该对象具有writeObject()方法,那么就会执行这一方法,否则就按默认方式序列化。在该对象的writeObjectt()方法中,可以先调用ObjectOutputStream的defaultWriteObject()方法,使得对象输出流先执行默认的序列化操作。同理可得出反序列化的情况,不过这次是defaultReadObject()方法。有些对象中包含一些敏感信息,这些信息不宜对外公开。如果按照默认方式对它们序列化,那么它们的序列化数据在网络上传输时,可能会被不法份子窃取。对于这类信息,可以对它们进行加密后再序列化,在反序列化时则需要解密,再恢复为原来的信息。默认的序列化方式会序列化整个对象图,这需要递归遍历对象图。如果对象图很复杂,递归遍历操作需要消耗很多的空间和时间,它的内部数据结构为双向列表。在应用时,如果对某些成员变量都改为transient类型,将节省空间和时间,提高序列化的性能。实现Externalizable接口Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为。Externalizable接口声明了两个方法:publicvoidwriteExternal(ObjectOutputout)throwslOExceptionpublicvoidreadExternal(ObjectInputin)throwslOException,ClassNotFoundException前者负责序列化操作,后者负责反序列化操作。在对实现了Externalizable接口的类的对象进行反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException:novalidconstructor异常。可序列化类的不同版本的序列化兼容性凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:1.privatestaticfinallongserialVersionUID;以上serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID,也有可能相同。为了提高哦啊serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。显式地定义serialVersionUID有两种用途:1)在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;2)在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUIDo谈谈序列化,关于.net中的二进制序列化和xml序列化2011-06-0114:26佚名17fx.Net我要评论(0)字号:T|T收藏序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。本文主要介绍.NET中的二进制序列化和XML序列化。AD:序列化技术,就是将对象持久存储。可以这样理解:序列化就是将对象占用的内存的数据copy到持久存储设备,比如硬盘。序列化有什么用呢?两点作用:1、持久的存储对象状态;2、分布式运算中传递数据的底层实现。.Net框架封装的序列化技术包含两种,即二进制序列化和xml序列化(以下代码都要求被序列化的对象的类型使用Serializable特征类)二进制序列化的实现(usingSystem.Runtime.Serialization.Formatters.Binary;)序列化代码://打开文件流FileStreamfs=newFileStream(保存序歹。化数据的文件路径,FileMode.OpenOrCreate);//创建二进制序列化对象BinaryFormatterbf=newBinaryFormatter();//调用二进制序列化对象的序列化方法执行序列化操作bf.Serialize(fs,被序歹。化的对象);//关闭文件流fs.Close();反序列化代码://打开文件流FileStreamfs=newFileStream(保存序歹。化数据的文件路径,FileMode.OpenOrCreate);//创建二进制序列化对象BinaryFormatterbf=newBinaryFormatter();//调用二进制序列化对象的反序列化方法执行反序列化操作从文件中反序列化得到的对象=bf.Deserialize(fs)as被序列化对象的类型;//关闭文件流fs.Close();XML序列化的实现(usingSystem.Xml.Serialization;)序列化代码://打开文件流FileStreamfs=newFileStream(保存序歹。化数据的文件路径,FileMode.OpenOrCreate);//创建XML序列化对象XmlSerializerxs=newXmlSerializer(typeof(被序歹。化对象的类型));//调用XML序列化对象的序列化方法执行序列化操作xs.Serialize(fs,被序歹。化的对象);//关闭文件流fs.Close();反序列化代码://打开文件流FileStreamfs=newFileStream(保存序歹。化数据的文件路径,FileMode.OpenOrCreate);//创建XML序列化对象XmlSerializerxs=newXmlSerializer(typeof(被序歹。化对象的类型));//调用XML序列化对象的反序列化方法执行反序列化操作从文件中反序列化得到的对象=xs.Deserialize(fs)as被序列化对象的类型;//关闭文件流fs.Close();当然这里所提供的是序列化和反序列化的默认实现,能应付大多数运用。特殊情况可以还需要重写序列化的默认实现。MSDN里面也有较详细的示例代码。深入C#序列化(Serialize)、反序列化

(Deserialize)(1)2011-06-0114:50望穿秋水博客园我要评论(0)字号:T|!.本文主要介绍了C#中的序列化和反序列化,序列化是.NET运行时环境用来支持用户定义类型的流化的机制,希望对你有帮助,一起来看吧。AD:序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。.NET框架提供了两种串行化的方式:1、是使用BinaryFormatter进行串行化;2、使用SoapFormatter进行串行化;3、使用XmlSerializer进行串行化。第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储;第三种其实和第二种差不多也是XML的格式存储,只不过比第二种的XML格式要简化很多(去掉了SOAP特有的额外信息)。可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、2可以使用[NonSerialized]属性来标志,2、可以使用[XmlIgnore]来标志。1、使用BinaryFormatter进行串行化下面是一个可串行化的类:usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSystem.Web.UI.HtmlControls;usingSystem.IO;usingSystem.Runtime.Serialization.Formatters.Binary;/**////<summary>///ClassToSerialize的摘要说明///</summary>[Serializable]publicclassClassToSerialize{publicintid=100;publicstringname="Name";[NonSerialized]publicstringSex="男";}下面是串行化和反串行化的方法:publicvoidSerializeNow(){ClassToSerializec=newClassToSerialize();FileStreamfileStream=newFileStream("c:\\temp.dat",FileMode.Create);BinaryFormatterb=newBinaryFormatter();b.Serialize(fileStream,c);fileStream.Close();}publicvoidDeSerializeNow(){ClassToSerializec=newClassToSerialize();c.Sex="kkkk";FileStreamfileStream=newFileStream("c:\\temp.dat",FileMode.Open,FileAccess.Read,FileShare.Read);BinaryFormatterb=newBinaryFormatter();c=b.Deserialize(fileStream)asClassToSerialize;Response.Write();Response.Write(c.Sex);fileStream.Close();}调用上述两个方法就可以看到串行化的结果:Sex属性因为被标志为[NonSerialized],故其值总是为null。2、使用SoapFormatter进行串行化和BinaryFormatter类似,我们只需要做一下简单修改即可:将using语句中的.Formatter.Binary改^.Formatter.Soap;将所有的BinaryFormatter替换为SoapFormatter.确保报存文件的扩展名为.xml经过上面简单改动,即可实现SoapFormatter的串行化,这时候产生的文件就是一个xml格式的文件。3、使用XmlSerializer进行串行化关于格式化器还有一个问题,假设我们需要XML,但是不想要SOAP特有的额外信息,那么我们应该怎么办呢?有两中方案:要么编写一个实现IFormatter接口的类,采用的方式类似于SoapFormatter类,但是没有你不需要的信息;要么使用库类XmlSerializer,这个类不使用Serializable属性,但是它提供了类似的功能。如果我们不想使用主流的串行化机制,而想使用XmlSeralizer进行串行化我们需要做一下修改:添加System.Xml.Serialization命名空间。Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的行为与NoSerialized类似。XmlSeralizer要求类有个默认的构造器,这个条件可能已经满足了。下面看示例:要序列化的类:usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSystem.Web.UI.HtmlControls;usingSystem.Xml.Serialization;[Serializable]publicclassPerson{privatestringname;publicstringName{get{returnname;}set{name=value;}}publicstringSex;publicintAge=31;publicCourse[]Courses;publicPerson()TOC\o"1-5"\h\z{}26.publicPerson(stringName){name=Name;Sex="男";}}[Serializable]publicclassCourse{publicstringName;[XmlIgnore]publicstringDescription;publicCourse(){}publicCourse(stringname,stringdescription){Name=name;Description=description;TOC\o"1-5"\h\z}}序列化和反序列化方法:publicvoidXMLSerialize(){Personc=newPerson("cyj");c.Courses=newCourse[2];c.Courses[0]=newCourse("英语","交流工具");c.Courses[1]=newCourse("数学","自然科学");XmlSerializerxs=newXmlSerializer(typeof(Person));Streamstream=newFileStream("c:\\cyj.XML",FileMode.Create,FileAccess.Write,FileShare.Read);xs.Serialize(stream,c);stream.Close();}publicvoidXMLDeserialize(){XmlSerializerxs=newXmlSerializer(typeof(Person));Streamstream=newFileStream("C:\\cyj.XML",FileMode.Open,FileAccess.Read,FileShare.Read);Personp=xs.Deserialize(stream)asPerson;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文档中也没有该节点,如下:<?xmlversion="1.0"?>〈Personxmlns:xsi="/2001/XMLSchema-instance"xmlns:xsd="/2001/XMLSchema"><Sex>M</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的类:usingSystem;usingSystem.Data;usingSystem.Configuration;usingSystem.Web;usingSystem.Web.Security;usingSystem.Web.UI;usingSystem.Web.UI.WebControls;usingSystem.Web.UI.WebControls.WebParts;usingSystem.Web.UI.HtmlControls;usingSystem.Runtime.Serialization;usi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论