热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#用XmlSerializer进行序列化和反序列化

和BinaryFormatter序列化一样,做一个可以序列化的类Person:namespaceSerializable{[Serializable]

和BinaryFormatter序列化一样,做一个可以序列化的类Person:

namespace Serializable
{
    [Serializable] //不可少! 
    public class Person
    {
        private String name;
        private String sex;
        private int age;

        public Person() //XmlSerializer序列化要求一定要有无参数构造函数 
        {
            name = "";
            sex = "";
            age = 0;
        }

        public Person(String n, String s, int a)
        {
            name = n;
            sex = s;
            age = a;
        }

        public String Name
        {
            get 
            {
                return name;
            }
            set 
            {
                name = value;
            }
        }

        public String Sex
        {
            get
            {
                return sex;
            }
            set
            {
                sex = value;
            }
        }

        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
            }
        }
    }
}

 

//主运行程序

namespace Serializable
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p1 = new Person("张三", "男", 20);
            //序列化
            try
            {
                FileStream fs = new FileStream("serialiable.xml", FileMode.Create);
                XmlSerializer xs = new XmlSerializer(typeof(Person));
                xs.Serialize(fs, p1);
                fs.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("序列化成功!");

            Console.Read();

            //反序列化
            try
            {
                FileStream fs = new FileStream("serialiable.xml", FileMode.Open, FileAccess.Read);
                XmlSerializer xs = new XmlSerializer(typeof(Person));
                Person p = (Person)xs.Deserialize(fs);
                Console.WriteLine(p.Name + p.Sex + p.Age);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.Read();
            Console.Read();
        }
    }
}

 

结果图:

 

生成的XML文件:

  1. 这篇随笔对应的.Net命名空间是System.Xml.Serialization;文中的示例代码需要引用这个命名空间。
  2. 为什么要做序列化和反序列化?
  3. .Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传递给其他系统使用;或者在关机时需要保存下来以便下次再次启动程序使用就需要序列化和反序列化。
  4. 范围:本文只介绍xml序列化,其实序列化可以是二进制的序列化,也可以是其他格式的序列化。
  5. 看一段最简单的Xml序列化代码
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. int i = 10;
  11. //声明Xml序列化对象实例serializer
  12. XmlSerializer serializer = new XmlSerializer(typeof(int));
  13. //执行序列化并将序列化结果输出到控制台
  14. serializer.Serialize(Console.Out, i);
  15. Console.Read();
  16. }
  17. }
  18. 上面代码对int i进行了序列化,并将序列化的结果输出到了控制台,输出结果如下
  19. "1.0" encoding="gb2312"?>
  20. <int>10int>
  21. 可以将上述序列化的xml进行反序列化&#xff0c;如下代码
  22. static void Main(string[] args)
  23. {
  24. using (StringReader rdr &#61; new StringReader(&#64;"
  25. 10"))
  26. {
  27. //声明序列化对象实例serializer
  28. XmlSerializer serializer &#61; new XmlSerializer(typeof(int));
  29. //反序列化&#xff0c;并将反序列化结果值赋给变量i
  30. int i &#61; (int)serializer.Deserialize(rdr);
  31. //输出反序列化结果
  32. Console.WriteLine("i &#61; " &#43; i);
  33. Console.Read();
  34. }
  35. }
  36. 以上代码用最简单的方式说明了xml序列化和反序列化的过程&#xff0c;.Net系统类库为我们做了大量的工作&#xff0c;序列化和反序列化都非常简单。但是在现实中业务需求往往比较复杂&#xff0c;不可能只简单的序列化一个int变量&#xff0c;显示中我们需要对复杂类型进行可控制的序列化。
  37. 自定义对象的Xml序列化&#xff1a;
  38. System.Xml.Serialization命名空间中有一系列的特性类&#xff0c;用来控制复杂类型序列化的控制。例如XmlElementAttribute、XmlAttributeAttribute、XmlArrayAttribute、XmlArrayItemAttribute、XmlRootAttribute等等。
  39. 看一个小例子&#xff0c;有一个自定义类Cat&#xff0c;Cat类有三个属性分别为Color&#xff0c;Saying&#xff0c;Speed。
  40. namespace UseXmlSerialization
  41. {
  42. class Program
  43. {
  44. static void Main(string[] args)
  45. {
  46. //声明一个猫咪对象
  47. var c &#61; new Cat { Color &#61; "White", Speed &#61; 10, Saying &#61; "White or black,  so long as the cat can catch mice,  it is a good cat" };
  48. //序列化这个对象
  49. XmlSerializer serializer &#61; new XmlSerializer(typeof(Cat));
  50. //将对象序列化输出到控制台
  51. serializer.Serialize(Console.Out, c);
  52. Console.Read();
  53. }
  54. }
  55. [XmlRoot("cat")]
  56. public class Cat
  57. {
  58. //定义Color属性的序列化为cat节点的属性
  59. [XmlAttribute("color")]
  60. public string Color { get; set; }
  61. //要求不序列化Speed属性
  62. [XmlIgnore]
  63. public int Speed { get; set; }
  64. //设置Saying属性序列化为Xml子元素
  65. [XmlElement("saying")]
  66. public string Saying { get; set; }
  67. }
  68. }
  69. 可以使用XmlElement指定属性序列化为子节点&#xff08;默认情况会序列化为子节点&#xff09;&#xff1b;或者使用XmlAttribute特性制定属性序列化为Xml节点的属性&#xff1b;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修饰属性。
  70. 对象数组的Xml序列化&#xff1a;
  71. 数组的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute&#xff1b;XmlArrayAttribute指定数组元素的Xml节点名&#xff0c;XmlArrayItemAttribute指定数组元素的Xml节点名。
  72. 如下代码示例&#xff1a;
  73. using System;
  74. using System.Collections.Generic;
  75. using System.Linq;
  76. using System.Text;
  77. using System.Xml.Serialization;
  78. namespace UseXmlSerialization
  79. {
  80. class Program
  81. {
  82. static void Main(string[] args)
  83. {
  84. //声明一个猫咪对象
  85. var cWhite &#61; new Cat { Color &#61; "White", Speed &#61; 10, Saying &#61; "White or black,  so long as the cat can catch mice,  it is a good cat" };
  86. var cBlack &#61; new Cat { Color &#61; "Black", Speed &#61; 10, Saying &#61; "White or black,  so long as the cat can catch mice,  it is a good cat" };
  87. CatCollection cc &#61; new CatCollection { Cats &#61; new Cat[] { cWhite,cBlack} };
  88. //序列化这个对象
  89. XmlSerializer serializer &#61; new XmlSerializer(typeof(CatCollection));
  90. //将对象序列化输出到控制台
  91. serializer.Serialize(Console.Out, cc);
  92. Console.Read();
  93. }
  94. }
  95. [XmlRoot("cats")]
  96. public class CatCollection
  97. {
  98. [XmlArray("items"),XmlArrayItem("item")]
  99. public Cat[] Cats { get; set; }
  100. }
  101. [XmlRoot("cat")]
  102. public class Cat
  103. {
  104. //定义Color属性的序列化为cat节点的属性
  105. [XmlAttribute("color")]
  106. public string Color { get; set; }
  107. //要求不序列化Speed属性
  108. [XmlIgnore]
  109. public int Speed { get; set; }
  110. //设置Saying属性序列化为Xml子元素
  111. [XmlElement("saying")]
  112. public string Saying { get; set; }
  113. }
  114. }
  115. 以上代码将输出&#xff1a;
  116. "1.0" encoding&#61;"gb2312"?>
  117. "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd&#61;"http://ww
  118. w.w3.org/2001/XMLSchema">
  119. "White">
  120. White or black,  so long as the cat can catch mice,  it is a good
  121. cat
  122. "Black">
  123. White or black,  so long as the cat can catch mice,  it is a good
  124. cat
  125. XmlSerializer内存泄漏问题&#xff1a;
  126. 仔细看了下msdn&#xff0c;确实存在泄漏的情况&#xff0c;msdn说明如下&#xff1a;
  127. 动态生成的程序集
  128. 为了提高性能&#xff0c;XML 序列化基础结构将动态生成程序集&#xff0c;以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生&#xff1a;
  129. XmlSerializer(Type)
  130. XmlSerializer.XmlSerializer(Type, String)
  131. 如果使用任何其他构造函数&#xff0c;则会生成同一程序集的多个版本&#xff0c;且绝不会被卸载&#xff0c;这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则&#xff0c;必须在 Hashtable 中缓存程序集&#xff0c;如以下示例中所示。
  132. 也就是说我们在使用XmlSerializer序列化&#xff0c;初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。
  133. XmlSerializer(Type)
  134. XmlSerializer.XmlSerializer(Type, String)




推荐阅读
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • HBase运维工具全解析
    本文深入探讨了HBase常用的运维工具,详细介绍了每种工具的功能、使用场景及操作示例。对于HBase的开发人员和运维工程师来说,这些工具是日常管理和故障排查的重要手段。 ... [详细]
  • 本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ... [详细]
  • 开发笔记:9.八大排序
    开发笔记:9.八大排序 ... [详细]
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • PHP 过滤器详解
    本文深入探讨了 PHP 中的过滤器机制,包括常见的 $_SERVER 变量、filter_has_var() 函数、filter_id() 函数、filter_input() 函数及其数组形式、filter_list() 函数以及 filter_var() 和其数组形式。同时,详细介绍了各种过滤器的用途和用法。 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 本文详细介绍了如何使用 PHP 接收并处理微信支付的回调结果,确保支付通知能够被正确接收和响应。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 黑马头条项目:Vue 文章详情模块与交互功能实现
    本文详细介绍了如何在黑马头条项目中配置文章详情模块的路由、获取和展示文章详情数据,以及实现关注、点赞、不喜欢和评论功能。通过这些步骤,您可以全面了解如何开发一个完整的前端文章详情页面。 ... [详细]
author-avatar
ESC咻咻_973
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有