对象的序列化 与 反序列化
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.Serialization.Formatters.Binary; 6 using System.IO; 7 8 namespace _07对象序列化 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 Person sly = new Person(); 15 sly.Name = "时绿艳"; 16 sly.Age = 16; 17 sly.Email = "sly@126.com"; 18 sly.MyCar = new Car("QQ"); 19 20 21 22 23 //对象序列化的步骤: 24 //1.创建二进制对象序列化器 25 BinaryFormatter bf = new BinaryFormatter(); 26 27 //创建一个文件流 28 using (FileStream fs = new FileStream("person.bin", FileMode.Create)) 29 { 30 //2.开始执行序列化 31 //将对象sly,序列化到fs文件流中,最终sly就保存到了person.bin文件中。 32 bf.Serialize(fs, sly); 33 } 34 Console.WriteLine("ok"); 35 Console.ReadKey(); 36 37 38 39 40 //现在要想存储sly这个对象,只能是,将【"时绿艳",16,"sly@126.com"】,只能将这些数据存储起来,下次用这些数据的时候,必须重新创建一个对象,然后这个对象的属性中的值,是来源于上个对象的。。 41 42 //思考:能不能直接把sly这个对象存储起来。这样的话,下次使用的时候直接拿来就是一个对象,不需要重新创建。 43 44 45 //Person sly2 = new Person(); 46 //sly2.Name = ""; 47 48 49 50 51 Console.WriteLine("ok"); 52 Console.ReadKey(); 53 } 54 } 55 56 57 [Serializable] 58 public class ShenWu 59 { 60 public void Say() 61 { 62 Console.WriteLine("新陈代谢!"); 63 } 64 } 65 66 //Person类型要想被序列化, 67 //1.必须Person类型本身是可序列化的(Person类型标记为可序列化) 68 //2.类中所有的字段属性的类型也必须标记为可序列化的。 69 //3.当前类型的所有父类也必须标记为可序列化的。 70 [Serializable] 71 public class Person : ShenWu 72 { 73 //2.建议,在使用序列化的时候尽量避免使用自动属性,因为自动属性,每次编译的时候自动生成的字段名可能不一样,所以在反序列化的时候可能会造成问题。 74 private string _name; 75 public string Name 76 { 77 get 78 { 79 return _name; 80 } 81 set 82 { 83 _name = value; 84 } 85 } 86 private int _age; 87 public int Age 88 { 89 get 90 { 91 return _age; 92 } 93 set 94 { 95 _age = value; 96 } 97 } 98 private string _email; 99 public string Email 100 { 101 get 102 { 103 return _email; 104 } 105 set 106 { 107 _email = value; 108 } 109 } 110 111 private Car _myCar; 112 113 public Car MyCar 114 { 115 get { return _myCar; } 116 set { _myCar = value; } 117 } 118 119 } 120 121 [Serializable] 122 public class Car 123 { 124 public Car(string brand) 125 { 126 this.Brand = brand; 127 } 128 private string _brand; 129 public string Brand 130 { 131 get 132 { 133 return _brand; 134 } 135 set 136 { 137 _brand = value; 138 } 139 } 140 } 141 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Runtime.Serialization.Formatters.Binary; 6 using System.IO; 7 using _07对象序列化; 8 9 namespace _08反序列化 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 //反序列化步骤: 16 //1.创建二进制序列化器(格式化器) 17 BinaryFormatter bf = new BinaryFormatter(); 18 19 using (FileStream fs = new FileStream("person.bin", FileMode.Open)) 20 { 21 //2.开始执行反序列化 22 //在执行反序列化的时候,由于person.bin中是存储的是原来Person类型序列化后的结果,所以要对person.bin反序列化时,需要Person类所在的程序集。 23 24 //问题:为什么反序列化的时候需要原来定义Person类的那个程序集? 25 //反序列话的时候,要返回一个对象,这个对象必须根据原来Person所在的程序集才能创建,也就是说person.bin中包含的仅仅是一些数据,根据这些数据是无法在内存中创建对象的。只能是根据原来Person类型的程序集来创建对象,然后把person.bin中的数据一一对应进行赋值。 26 //object obj = bf.Deserialize(fs); 27 //对象序列化,只是对对象的一些状态信息进行序列化(比如:字段)。 28 //对于方法之类的根本不进行序列化,也就是说person.bin中只包含字段名和字段值,根本没有方法信息。但是反序列化的时候,返回的是一个对象,那么只根据这些字段信息是无法创建对象的,所以这个时候需要先根据原来的程序集,获取Person类型,然后在内存中创建一个Person对象,然后再把反序列化得到的字段信息赋值给这个Person对象。 29 30 Person per = (Person)bf.Deserialize(fs); 31 Console.WriteLine("Name:{0},Age:{1},Car:{2}", per.Name, per.Age, per.MyCar.Brand); 32 } 33 Console.WriteLine("ok"); 34 Console.ReadKey(); 35 36 } 37 } 38 }