C# 二进制BinaryFormatter和Xml进行序列化与反序列化

序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。

.NET框架提供了两种种串行化的方式:1、是使用BinaryFormatter进行串行化;2、使用XmlSerializer进行串行化。第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储。    可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、可以使用[NonSerialized]属性来标志,2、可以使用[XmlIgnore]来标志。

序列化意思指的是把对象的当前状态进行持久化,一个对象的状态在面向对象的程序中是由属性表示的,所以序列化类的时候是从属性读取值以某种格式保存下来,而类的成员函数不会被序列化,.net存在几种默认提供的序列化,二进制序列化,xml和json序列化会序列化所有的实例共有属性。

  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using System.IO;
  5. using System.Collections.Generic;
  6. using System.Runtime.Serialization.Formatters.Binary;
  7. [ Serializable] // 表示该类可以被序列化
  8. class Person
  9. {
  10. private string name;
  11. [ NonSerialized] // 表示下面这个age字段不进行序列化
  12. private int age;
  13. public string Name
  14. {
  15. get { return name;}
  16. set { name = value;}
  17. }
  18. public int Age
  19. {
  20. get { return age;}
  21. set { age = value;}
  22. }
  23. public Person() { }
  24. public Person(string name, int age)
  25. {
  26. this.name = name;
  27. this.age = age;
  28. }
  29. public void SayHi()
  30. {
  31. Debug.LogFormat ( "我是{0}, 今年{1}岁", name, age);
  32. }
  33. }
  34. public class BinarySerializer : MonoBehaviour {
  35. string filePath = Directory.GetCurrentDirectory() + "/binaryFile.txt";
  36. // Use this for initialization
  37. void Start () {
  38. List<Person> listPers = new List<Person> ();
  39. Person per1 = new Person ( "张三", 18);
  40. Person per2 = new Person ( "李四", 20);
  41. listPers.Add (per1);
  42. listPers.Add (per2);
  43. SerializeMethod (listPers); // 序列化
  44. DeserializeMethod(); // 反序列化
  45. Debug.Log( "Done ! ");
  46. }
  47. void DeserializeMethod() // 二进制反序列化
  48. {
  49. FileStream fs = new FileStream (filePath, FileMode.Open);
  50. BinaryFormatter bf = new BinaryFormatter ();
  51. List<Person> list = bf.Deserialize (fs) as List<Person>;
  52. if (list != null)
  53. {
  54. for ( int i = 0; i < list.Count; i++)
  55. {
  56. list [i].SayHi ();
  57. }
  58. }
  59. fs.Close ();
  60. }
  61. void SerializeMethod(List<Person> listPers) // 二进制序列化
  62. {
  63. FileStream fs = new FileStream (filePath, FileMode.Create);
  64. BinaryFormatter bf = new BinaryFormatter ();
  65. bf.Serialize (fs, listPers);
  66. fs.Close ();
  67. }
  68. // Update is called once per frame
  69. void Update () {
  70. }
  71. }


序列化的文本打开后,内容如下所示:


反序列化输出结果:

大家好,我是张三,今年0岁

大家好,我是李四,今年0岁

由此看出,未序列化的字段存储的值为空

使用XmlSerializer进行串行化
    关于格式化器还有一个问题,假设我们需要XML,有两中方案:要么编写一个实现IFormatter接口的类,采用的方式类似于SoapFormatter类,但是没有你不需要的信息;要么使用库类XmlSerializer,这个类不使用Serializable属性,但是它提供了类似的功能。
    如果我们不想使用主流的串行化机制,而想使用XmlSeralizer进行串行化我们需要做一下修改:
    a.添加System.Xml.Serialization命名空间。
    b.Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的行为与NoSerialized类似。
    c.XmlSeralizer要求类有个默认的构造器,这个条件可能已经满足了。
序列化:

XmlSerializer xs = new XmlSerializer(typeof(List<Peoson>));
xs.Serialize(fs, listPers);
反序列化:

XmlSerializer xs = new XmlSerializer(typeof(List<Peoson>));
List<Peoson> list = xs.Deserialize(fs) as List<Peoson>;

  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using System.IO;
  5. using System.Xml.Serialization;
  6. using System.Xml;
  7. using System.Collections.Generic;
  8. [ Serializable] // 表示该类可以被序列化
  9. [ XmlRoot("AAA")] // 设置为XML中的根元素名称
  10. public class Person
  11. {
  12. private string name;
  13. private int age;
  14. // [XmlElement("abc")]
  15. public int abc = 1000; // 类的public属性字段都可以被序列化
  16. // [XmlAttribute("Name")] 设置作为xml中的属性
  17. public string Name
  18. {
  19. get { return name;}
  20. set { name = value;}
  21. }
  22. // [XmlElement("Age")] 设置作为XML中的元素(默认状态)
  23. public int Age
  24. {
  25. get { return age;}
  26. set { age = value;}
  27. }
  28. public Person() { }
  29. public Person(string name, int age)
  30. {
  31. this.name = name;
  32. this.age = age;
  33. }
  34. public void SayHi()
  35. {
  36. Debug.LogFormat ( "我是{0}, 今年{1}岁", name, age);
  37. }
  38. }
  39. public class XmlSerialize : MonoBehaviour {
  40. string filePath = Directory.GetCurrentDirectory() + "/XmlFile.txt";
  41. string filePath2 = Directory.GetCurrentDirectory() + "/XmlClassFile.txt";
  42. // Use this for initialization
  43. void Start () {
  44. List<Person> listPers = new List<Person> ();
  45. Person per1 = new Person ( "张三", 18);
  46. Person per2 = new Person ( "李四", 20);
  47. listPers.Add (per1);
  48. listPers.Add (per2);
  49. SerializeMethod (listPers); // 序列化
  50. DeserializeMethod(); // 反序列化
  51. // SerializeClassMethod (per1);
  52. // DeserializeClassMethod ();
  53. Debug.Log( "Done ! ");
  54. }
  55. void DeserializeClassMethod() // Xml实体类反序列化
  56. {
  57. FileStream fs = new FileStream (filePath, FileMode.Open);
  58. XmlSerializer xs = new XmlSerializer( typeof(Person));
  59. Person p = xs.Deserialize (fs) as Person;
  60. if (p != null)
  61. {
  62. p.SayHi ();
  63. }
  64. fs.Close ();
  65. }
  66. void SerializeClassMethod(Person p) // Xml实体类序列化
  67. {
  68. FileStream fs = new FileStream (filePath2, FileMode.Create);
  69. XmlSerializer xs = new XmlSerializer( typeof(Person));
  70. xs.Serialize(fs, p);
  71. fs.Close ();
  72. }
  73. void DeserializeMethod() // Xml列表反序列化
  74. {
  75. FileStream fs = new FileStream (filePath, FileMode.Open);
  76. XmlSerializer xs = new XmlSerializer( typeof(List<Person>));
  77. List<Person> listPers = xs.Deserialize (fs) as List<Person>;
  78. if (listPers != null)
  79. {
  80. for ( int i = 0; i < listPers.Count; i++)
  81. {
  82. listPers [i].SayHi ();
  83. }
  84. }
  85. fs.Close ();
  86. }
  87. void SerializeMethod(List<Person> listPers) // Xml列表序列化
  88. {
  89. FileStream fs = new FileStream (filePath, FileMode.Create);
  90. XmlSerializer xs = new XmlSerializer( typeof(List<Person>));
  91. xs.Serialize(fs, listPers);
  92. fs.Close ();
  93. }
  94. // Update is called once per frame
  95. void Update () {
  96. }
  97. }

Xml列表序列化的内容:



Xml实体类序列化的内容:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值