




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实例解析C+/CLI的串行化- 串行化可使对象被转换为某种外部的形式,比如以文件存储的形式供程序使用,或通过程序间的通讯发送到另一个处理过程。转换为外部形式的过程称为串行化,而逆过程称为反串行化。 简介 请看例1中的示例,其将多个对象类型的值写入到一个新的磁盘文件中,关闭文件,接着再把这些值重新读取到内存中。例1:using namespace System;using namespace System:IO;using namespace System:Runtime:Serialization:Formatters:Binary;int main()array intArray = 10, 20, 30;array floatArray = 1.2F, 2.4F,3.5F, 6.8F,8.4F, 9.7F;DateTime dt = DateTime:Now;Console:WriteLine(dt 0Serialize(file, Hello);/*3b*/ formatter-Serialize(file, intArray);/*3c*/ formatter-Serialize(file, floatArray);/*3d*/ formatter-Serialize(file, true);/*3e*/ formatter-Serialize(file, dt);/*3f*/ formatter-Serialize(file, 1000);/*3g*/ formatter-Serialize(file, LX);/*3h*/ formatter-Serialize(file, 1.23456F);/*4*/ file-Close();/从文件中反串行化数据-即读取数据/*5*/ file = File:Open(Sr01.ser, FileMode:Open);/*6a*/ String s = static_cast(formatter-Deserialize(file);Console:WriteLine(String 0, s);/*6b*/ array newIntArray = static_castarray(formatter-Deserialize(file);Console:WriteLine(newIntArray:);for (int i = 0; i Length; +i)Console:Write( 0, newIntArrayi);Console:WriteLine();/*6c*/ array newFloatArray =static_castarray(formatter-Deserialize(file);Console:WriteLine(newFloatArray:);for (int i = 0; i 3; +i)for (int j = 0; j 2; +j)Console:Write( 0, newFloatArrayi,j);Console:WriteLine();/*6d*/ bool b = static_cast(formatter-Deserialize(file);Console:WriteLine(bool 0, b);/*6e*/ DateTime newDT = static_cast(formatter-Deserialize(file);Console:WriteLine(newDT 0, newDT);/*6f*/ int v = static_cast(formatter-Deserialize(file);Console:WriteLine(int 0, v);/*6g*/ wchar_t c = static_cast(formatter-Deserialize(file);Console:WriteLine(wchar_t 0, c);/*6h*/ float f = static_cast(formatter-Deserialize(file);Console:WriteLine(float 0Close(); 在标记1中,我们定义了一个BinaryFormatter类型的变量,此种类型的任意对象都可以二进制的形式进行串行与反串行化。在标记2中,用指定的名称创建了一个新的文件,后缀 .ser没有特别的意思,这是约定俗成的表示这是一个串行化数据文件。从标记3a至3h,表示一个对象被串行化至文件中。在字符串的情况下,每个字符都被写入;在数组的情况下,所有元素都被写入;在日期时间的情况下,类型中包含的所有数据及有关依赖项都被写入;在为原始类型值的情况下,它们先被装箱,然后对应的对象被写入。上述动作中,串行化只需要接收一个Object类型参数的对象即可。通过调用Deserialize函数,可取回串行化后的数据,如标记6a中所示;因为此函数返回一个Object类型的值,所以需要把它转换为相应的值。程序的输出如插1所示:插1:例1中串行化、反串行化的输出String HelloTrue9/29/2005 3:25:44 PM1000X1.23456ReadLine() != nullptr)/*2*/ dictionary-Add(str, nullptr);inStream-Close();/*3*/ Console:WriteLine(Dictionary contains 0 entries, dictionary-Count);BinaryFormatter formatter = gcnew BinaryFormatter();Stream file = File:Open(dictionary.ser, FileMode:Create);/*4*/ formatter-Serialize(file, dictionary);file-Close(); 在标记1中,我们先分配了一个初始化为21000个条目的哈希表(这样做只是为了加快处理速度,在条目相加时不需要重新进行分配),接着从一个文本文件中,一次一行地读入字,并将其添加到标记2的哈希表中。请注意,在定义中,哈希表的每个条目都由(键/值)对组成。但在我们的程序中,键也是值,所以在第二个参数中使用了nullprt。哈希表中的键值必须是唯一的,而添加进来的任何类型的对象都必须重载System:对象名 GetHashCode函数-字符串也一样。一旦文件中所有的字被读取并添加到哈希表中,就可通过一个简单的Serialize调用,把哈希表写到磁盘上,如标记4所示。在例3中,我们读入这个字典,并在其中查找用户提供的字,插2是对应的输出。例3:using namespace System;using namespace System:IO;using namespace System:Collections;using namespace System:Runtime:Serialization:Formatters:Binary;int main()BinaryFormatter formatter = gcnew BinaryFormatter;Stream file = File:Open(dictionary.ser, FileMode:Open);/*1*/ Hashtable dictionary = static_cast(formatter-Deserialize(file);file-Close();/*2*/ Console:WriteLine(Dictionary contains 0 entries, dictionary-Count);String word;while (true)Console:Write(Enter a word: );word = Console:ReadLine();if (word = nullptr)break; /*3*/ Console:WriteLine(01 found, word, (dictionary-Contains(word) ? : not); 插2:使用反串行化进行字典查找Dictionary contains 20159 entriesEnter a word: househouse foundEnter a word: houseshouses not foundEnter a word: brickbrick foundEnter a word: manlymanly not found 此处最重要的是,我们能在单个函数调用中,串行、反串行化任意大小、任意复杂性的对象。处理多个句柄当我们传递一个对象的句柄给Serialize时,似乎会在底层对对象进行一个复制,那么,实际情况真的是这样吗?假设我们把包含有多个句柄的一个对象写入到其他对象中,或者我们调用Serialize两次,每次都给它同一个对象的句柄呢?我们真的想得到同一对象的多个副本吗?在例4中演示了这个过程:例4:using namespace System;using namespace System:IO;using namespace System:Runtime:Serialization:Formatters:Binary;/*1*/ Serializable ref class Employee /* . */;int main() Employee emp1 = gcnew Employee();Employee emp2 = gcnew Employee();Employee emp3 = emp2;/*2a*/ Console:WriteLine(emp1 = emp2 is 0, (emp1 = emp2);/*2b*/ Console:WriteLine(emp2 = emp3 is 0, (emp2 = emp3);/*2c*/ Console:WriteLine(emp1 = emp3 is 0, (emp1 = emp3);array list = gcnew array(2);list0 = emp1;list1 = list0;/*2d*/ Console:WriteLine(list0 = list1 is 0, (list0 = list1);/*2e*/ Console:WriteLine(list0 = emp1 is 0, (list0 = emp1);/*2f*/ Console:WriteLine(list1 = emp1 is 0, (list1 = emp1);/将数据串行化到文件BinaryFormatter formatter = gcnew BinaryFormatter;Stream file = File:Open(Sr03.ser, FileMode:Create);/*3a*/ formatter-Serialize(file, emp1);/*3b*/ formatter-Serialize(file, emp2);/*3c*/ formatter-Serialize(file, emp3);/*3d*/ formatter-Serialize(file, list);file-Close();/从文件中反串行化数据-即读取数据file = File:Open(Sr03.ser, FileMode:Open);/*4a*/ emp1 = static_cast(formatter-Deserialize(file);/*4b*/ emp2 = static_cast(formatter-Deserialize(file);/*4c*/ emp3 = static_cast(formatter-Deserialize(file);/*4d*/ list = static_castarray(formatter-Deserialize(file);file-Close();/*5a*/ Console:WriteLine(emp1 = emp2 is 0, (emp1 = emp2);/*5b*/ Console:WriteLine(emp2 = emp3 is 0, (emp2 = emp3);/*5c*/ Console:WriteLine(emp1 = emp3 is 0, (emp1 = emp3);/*5d*/ Console:WriteLine(list0 = list1 is 0, (list0 = list1);/*5e*/ Console:WriteLine(list0 = emp1 is 0, (list0 = emp1);/*5f*/ Console:WriteLine(list1 = emp1 is 0, (list1 = emp1); 在本例中,我们想对Employee类型(在标记1中的用户自定义类型)的对象进行串行化,必须把Serializable属性附加到这个类型上。如果我们试图串行化一个没有标明此属性的类对象,将会抛出一个System:Runtime:Serialization:SerializationException类型的异常。串行化之前的程序输出如插3所示:插3:串行化之前例4的输出emp1 = emp2 is Falseemp2 = emp3 is Trueemp1 = emp3 is Falselist0 = list1 is Truelist0 = emp1 is Truelist1 = emp1 is True 我们对四个目标进行了串行化,前两个代表了不同的Employee对象,而第三个是对第二个的引用,第四个为包含两个元素的数组,这两个元素均引用第一个Employee对象。程序的输出表明了它们之间的这些关系,反串行化之后的输出见插4:插4:反串行化之后例4的输出emp1 = emp2 is Falseemp2 = emp3 is Falseemp1 = emp3 is Falselist0 = list1 is Truelist0 = emp1 is Falselist1 = emp1 is False 注意,现在第三个Employee句柄已不再是一个指向第二个Employee对象的句柄了,类似地,尽管list0与list1都引用同一个Empolyee对象,但对象已不是我们取回的第一个对象了。在此应看到,当多个对象逐个串行化之后,它们是相关联的,而当反串行化之后,它们的关系并没有因此而恢复,但是,对象内部的关系仍然被维持。自定义的串行化默认情况下,当一个对象被串行化时,所有的非静态实例字段都会被写入,并在反串行化期间顺序读回;然而,对包含静态字段的类,这可能会导致一个问题。在例5中使用了Point类,其不但包含了用于追踪每个Point x与y坐标的实例变量,而且还会跟踪在程序执行期间创建的Point数目。例如,在例5中,通过显示构造函数调用,创建了4个Point,并将它们串行化到磁盘;当它们被反串行化时,又创建了4个新的Point,因此Point总数现在为8,插5中是程序的输出:例5:using namespace System;using namespace System:IO;using namespace System:Runtime:Serialization:Formatters:Binary;int main() Console:WriteLine(PointCount: 0, Point:PointCount);Point p1 = gcnew Point(15, 10);Point p2 = gcnew Point(-2, 12);array p3 = gcnew Point(18, -5), gcnew Point(25, 19);Console:WriteLine(PointCount: 0, Point:PointCount);BinaryFormatter formatter = gcnew BinaryFormatter;Stream file = File:Open(Point.ser, FileMode:Create);formatter-Serialize(file, p1);formatter-Serialize(file, p2);formatter-Serialize(file, p3);file-Close();file = File:Open(Point.ser, FileMode:Open);Point p4 = static_cast(formatter-Deserialize(file);Console:WriteLine(PointCount: 0, Point:PointCount);Point p5 = static_cast(formatter-Deserialize(file);Console:WriteLine(PointCount: 0, Point:PointCount);array p6 = static_castarray(formatter-Deserialize(file);Console:WriteLine(PointCount: 0, Point:PointCount);file-Close();Console:WriteLine(p1: 0, p4: 1, p1, p4);Console:WriteLine(p2: 0, p5: 1, p2, p5);Console:WriteLine(p30: 0, p60: 1, p30, p60);Console:WriteLine(p31: 0, p61: 1, p31, p61); 插5:反串行化创建了4个新的PointPointCount: 0PointCount: 4PointCount: 5PointCount: 6PointCount: 8p1: (15,10),
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年金融行业数据分析师面试模拟题及策略分析
- 2025年心理咨询师资格认证模拟题及参考答案
- 2025年电子商务师高级考试试题及解析与答案
- 2025年交通安全问答试题及答案
- 2025年轨道交通调度员(技师)职业技能鉴定考试题库及答案(浓缩50题)
- 2025注册验船师资格考试(B级船舶检验法律法规)模拟试题及答案一
- 2025年能源资源管理与可持续发展考题及答案
- 桃花源记课件深圳
- 陕西省四校联考2026届化学高一第一学期期中调研试题含解析
- 桃源消防知识培训讲座课件
- 设备基础知识-动设备课件
- GB/T 12599-2002金属覆盖层锡电镀层技术规范和试验方法
- FZ/T 01057.2-2007纺织纤维鉴别试验方法 第2部分:燃烧法
- 面条制品-课件
- 2023年西安陕鼓动力股份有限公司招聘笔试题库及答案解析
- 四上科学第一单元《多样的动物》知识梳理
- 放射源辐射事故专项应急预案
- 微观经济学-范里安varian中级
- (完整)人教版高一英语必修一单词表
- 《印章移交登记表》
- 电缆护套感应电压计算
评论
0/150
提交评论