序列化是将对象转换成字节流的过程,反序列化是把字节流转换成对象的过程。对象一旦被序列化,就可以把对象状态保存到硬盘的某个位置,甚至还可以通过网络发送给另外一台机器上运行的进程。本篇主要包括:

使用BinaryFormatter类进行序列化和反序列化
使用ISerializable接口自定义序列化过程
使用XmlSerializer类进行序列化和反序列化

□ 使用BinaryFormatter类进行序列化和反序列化

首先把需要序列化的类打上[Serializable]特性,如果某个字段不需要被序列化,就打上[NonSerialized]特性。

  1.     [Serializable]
  2.  
  3.     public class Meeting
  4.  
  5.     {
  6.  
  7.         public string _name;
  8.  
  9.         [NonSerialized]
  10.  
  11.         public string _location;
  12.  
  13.         public Meeting(string name, string location)
  14.  
  15.         {
  16.  
  17.             this._name = name;
  18.  
  19.             this._location = location;
  20.  
  21.         }
  22.  
  23.     }
  24.  

对象序列化后需要一个载体文件,以下的Meeting.binary文件用来存储对象的状态。

  1.         static void Main(string[] args)
  2.  
  3.         {
  4.  
  5.             Meeting m1 = new Meeting("年终总结","青岛");
  6.  
  7.             Meeting m2;
  8.  
  9.             //先序列化
  10.  
  11.             SerializedWithBinaryFormatter(m1,"Meeting.binary");
  12.  
  13.             m2 = (Meeting) DeserializeWithBinaryFormatter("Meeting.binary");
  14.  
  15.             Console.WriteLine(m2._name);
  16.  
  17.             Console.WriteLine(m2._location  ?? "_location字段没有被序列化");
  18.  
  19.             Console.ReadKey();
  20.  
  21.         }
  22.  
  23.         //序列化
  24.  
  25.         static void SerializedWithBinaryFormatter(object obj, string fileName)
  26.  
  27.         {
  28.  
  29.             //打开文件写成流
  30.  
  31.             Stream streamOut = File.OpenWrite(fileName);
  32.  
  33.             BinaryFormatter formatter = new BinaryFormatter();
  34.  
  35.             //把对象序列化到流中
  36.  
  37.             formatter.Serialize(streamOut, obj);
  38.  
  39.             //关闭流
  40.  
  41.             streamOut.Close();
  42.  
  43.         }
  44.  
  45.         //反序列化
  46.  
  47.         static object DeserializeWithBinaryFormatter(string fileName)
  48.  
  49.         {
  50.  
  51.             //打开文件读成流
  52.  
  53.             Stream streamIn = File.OpenRead(fileName);
  54.  
  55.             BinaryFormatter formatter = new BinaryFormatter();
  56.  
  57.             object obj = formatter.Deserialize(streamIn);
  58.  
  59.             streamIn.Close();
  60.  
  61.             return obj;
  62.  
  63.         }
  64.  

Meeting.binary文件在bin/debug文件夹中。

□ 使用ISerializable接口自定义序列化过程

如果想对序列化的过程有更多的控制,应该使用ISerializable接口,通过它的GetObjectData方法可以改变对象的字段值。

  1.   [Serializable]
  2.  
  3.     public class Location : ISerializable
  4.  
  5.     {
  6.  
  7.         public int x;
  8.  
  9.         public int y;
  10.  
  11.         public string name;
  12.  
  13.         public Location(int x, int y, string name)
  14.  
  15.         {
  16.  
  17.             this.x = x;
  18.  
  19.             this.y = y;
  20.  
  21.             this.name = name;
  22.  
  23.         }
  24.  
  25.         protected Location(SerializationInfo info, StreamingContext context)
  26.  
  27.         {
  28.  
  29.             x = info.GetInt32("i");
  30.  
  31.             y = info.GetInt32("j");
  32.  
  33.             name = info.GetString("k");
  34.  
  35.         }
  36.  
  37.         public void GetObjectData(SerializationInfo info, StreamingContext context)
  38.  
  39.         {
  40.  
  41.             info.AddValue("i", x + 1);
  42.  
  43.             info.AddValue("j", y + 1);
  44.  
  45.             info.AddValue("k", name + "HELLO");
  46.  
  47.         }
  48.  
  49.     }
  50.  

以上,不仅要实现接口方法GetObjectData,还需要提供对象的重载构造函数,从SerializationInfo实例中获取值。

在客户端:

  1.             Location loc1 = new Location(1,2,"qingdao");
  2.  
  3.             Location loc2;
  4.  
  5.             //序列化
  6.  
  7.             SerializedWithBinaryFormatter(loc1, "Location.binary");
  8.  
  9.             loc2 = (Location) DeserializeWithBinaryFormatter("Location.binary");
  10.  
  11.             Console.WriteLine(loc2.x);
  12.  
  13.             Console.WriteLine(loc2.y);
  14.  
  15.             Console.WriteLine(loc2.name);
  16.  
  17.             Console.ReadKey();
  18.  

以上,使用BinaryFormatter类进行序列化和反序列化,存储的文件格式是二进制的,例如,打开Meeting.binary文件,我们看到:

有时候,我们希望文件的格式是xml。

□ 使用XmlSerializer类进行序列化和反序列化

XmlSerializer类进行序列化的存储文件是xml格式。用XmlSerializer类进行序列化的类不需要打上[Serializable]特性。

  1.     public class Car
  2.  
  3.     {
  4.  
  5.         [XmlAttribute(AttributeName = "model")]
  6.  
  7.         public string type;
  8.  
  9.         public string code;
  10.  
  11.         [XmlIgnore]
  12.  
  13.         public int age;
  14.  
  15.         [XmlElement(ElementName = "mileage")]
  16.  
  17.         public int miles;
  18.  
  19.         public Status status;
  20.  
  21.         public enum Status
  22.  
  23.         {
  24.  
  25.             [XmlEnum("使用中")]
  26.  
  27.             Normal,
  28.  
  29.             [XmlEnum("修复中")]
  30.  
  31.             NotUse,
  32.  
  33.             [XmlEnum("不再使用")]
  34.  
  35.             Deleted
  36.  
  37.         }
  38.  
  39.     }
  40.  

在客户端:

  1.             //打开写进流
  2.  
  3.             Stream streamOut = File.OpenWrite("Car.xml");
  4.  
  5.             System.Xml.Serialization.XmlSerializer x = new XmlSerializer(car1.GetType());
  6.  
  7.             //序列化到流中
  8.  
  9.             x.Serialize(streamOut, car1);
  10.  
  11.             streamOut.Close();
  12.  
  13.             //打开读流
  14.  
  15.             Stream streamIn = File.OpenRead("Car.xml");
  16.  
  17.             //反序列化
  18.  
  19.             Car car2 = (Car) x.Deserialize(streamIn);
  20.  
  21.             Console.WriteLine(car2.type);
  22.  
  23.             Console.WriteLine(car2.code);
  24.  
  25.             Console.WriteLine(car2.miles);
  26.  
  27.             Console.WriteLine(car2.status);
  28.  
  29.             Console.ReadKey();
  30.  

运行,打开bin/debug中的Car.xml文件如下:

  1. <?xml version="1.0"?>
  2.  
  3. <Car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" model="sedan">
  4.  
  5.   <code>001</code>
  6.  
  7.   <mileage>1000</mileage>
  8.  
  9.   <status>使用中</status>
  10.  
  11. </Car>

○ 类名Car成了xml的根节点
○ 打上[XmlAttribute(AttributeName = "model")]特性的字段变成了根节点的属性,AttributeName为属性别名
○ 枚举项可打上[XmlEnum("使用中")]特性

如果一个类中包含集合属性,比如以下的Department类包含一个类型List<Employee>的集合属性Employees。

  1.    public class Department
  2.  
  3.     {
  4.  
  5.         public Department()
  6.  
  7.         {
  8.  
  9.             Employees = new List<Employee>();
  10.  
  11.         }
  12.  
  13.         public string Name { get; set; }
  14.  
  15.         [XmlArray("Staff")]
  16.  
  17.         public List<Employee> Employees { get; set; }
  18.  
  19.     }
  20.  
  21.     public class Employee
  22.  
  23.     {
  24.  
  25.         public string Name { get; set; }
  26.  
  27.         public Employee()
  28.  
  29.         {
  30.  
  31.         }
  32.  
  33.         public Employee(string name)
  34.  
  35.         {
  36.  
  37.             Name = name;
  38.  
  39.         }
  40.  
  41.     }
  42.  

在客户端:

  1.     class Program
  2.  
  3.     {
  4.  
  5.         static void Main(string[] args)
  6.  
  7.         {
  8.  
  9.             var department = new Department();
  10.  
  11.             department.Name = "销售部";
  12.  
  13.             department.Employees.Add(new Employee("张三"));
  14.  
  15.             department.Employees.Add(new Employee("李四"));
  16.  
  17.             XmlSerializer serializer = new XmlSerializer(department.GetType());
  18.  
  19.             //打开写进流
  20.  
  21.             Stream streamOut = File.OpenWrite("Department.xml");
  22.  
  23.             serializer.Serialize(streamOut, department);
  24.  
  25.             streamOut.Close();
  26.  
  27.         }
  28.  
  29.     }
  30.  

查看bin/debug中的Department.xml文件。

  1. <?xml version="1.0"?>
  2.  
  3. <Department xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  4.  
  5.   <Name>销售部</Name>
  6.  
  7.   <Staff>
  8.  
  9.     <Employee>
  10.  
  11.       <Name>张三</Name>
  12.  
  13.     </Employee>
  14.  
  15.     <Employee>
  16.  
  17.       <Name>李四</Name>
  18.  
  19.     </Employee>
  20.  
  21.   </Staff>
  22.  
  23. </Department>

总结:
1、使用BinaryFormatter类序列化到二进制文件
2、使用XmlSerializer类序列化到xml文件
3、使用ISerializable接口自定义序列化过程

初识序列化和反序列化,使用BinaryFormatter类、ISerializable接口、XmlSerializer类进行序列化和反序列化的更多相关文章

  1. 谁能在同一文件序列化多个对象并随机读写(反序列化)?BinaryFormatter、SoapFormatter、XmlSerializer还是BinaryReader

    谁能在同一文件序列化多个对象并随机读写(反序列化)?BinaryFormatter.SoapFormatter.XmlSerializer还是BinaryReader 随机反序列化器 +BIT祝威+悄 ...

  2. 数据结构-List接口-LinkedList类-Set接口-HashSet类-Collection总结

    一.数据结构:4种--<需补充> 1.堆栈结构:     特点:LIFO(后进先出);栈的入口/出口都在顶端位置;压栈就是存元素/弹栈就是取元素;     代表类:Stack;     其 ...

  3. .NET中XML序列化和反序列化常用类和用来控制XML序列化的属性总结(XmlSerializer,XmlTypeAttribute,XmlElementAttribute,XmlAttributeAttribute,XmlArrayAttribute...)

    序列化和反序列化是指什么? 序列化(seriallization): 将对象转化为便于传输的数据格式, 常见的序列化格式:二进制格式,字节数组,json字符串,xml字符串.反序列化(deserial ...

  4. ISerializable接口

    继承ISerializable接口可以灵活控制序列化过程 格式化器的工作流程:格式化器再序列化一个对象的时候,发现对象继承了ISerializable接口,那它就会忽略掉类型所有的序列化特性,转而调用 ...

  5. typescript可索引接口 类类型接口

    /* 接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用.接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据, ...

  6. java类生命周期,类的“加载,连接,初始化,使用,卸载过程”详解

    “ 如果说核心类库的 API 比做数学公式的话,那么 Java 虚拟机的知识就好比公式的推导过程” 每本Java入门书籍在介绍Java这门语言的时候都会提到Java跨平台,“一次解释,到处运行的特点“ ...

  7. Typescript中的可索引接口 类类型接口

    /* 5.typeScript中的接口 可索引接口 类类型接口 */ /* 接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用 ...

  8. Java基础进阶:多态与接口重点摘要,类和接口,接口特点,接口详解,多态详解,多态中的成员访问特点,多态的好处和弊端,多态的转型,多态存在的问题,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    多态与接口重点摘要 接口特点: 接口用interface修饰 interface 接口名{} 类实现接口用implements表示 class 类名 implements接口名{} 接口不能实例化,可 ...

  9. 序列化流与反序列化流,打印流,工具类commons-IO

    1序列化流与反序列化流 用于从流中读取对象的操作流 ObjectInputStream    称为 反序列化流 用于向流中写入对象的操作流 ObjectOutputStream   称为 序列化流 特 ...

随机推荐

  1. linux内存管理-内核用户空间 【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-4491362.html 1,linux内存管理中几个重要的结构体和数组 page unsigned long ...

  2. linux du查询目录所占的磁盘空间

    linux查询目录所占的磁盘空间 du -hxs /* --exclude=/proc |sort -rh 命令和选项的解释: du – 估计文件的空间使用情况 -hsx – (-h)更易读的格式,( ...

  3. 爬虫、框架scrapy

    阅读目录 一 介绍 二 安装 三 命令行工具 四 项目结构以及爬虫应用简介 五 Spiders 六 Selectors 七 Items 八 Item Pipeline 九 Dowloader Midd ...

  4. Project Euler Problem3

    Largest prime factor Problem 3 The prime factors of 13195 are 5, 7, 13 and 29. What is the largest p ...

  5. 错误的理解引起的bug async await 执行顺序

    今天有幸好碰到一个bug,让我知道了之前我对await async 的理解有点偏差. 错误的理解 之前我一直以为  await 后面的表达式,如果是直接返回一个具体的值就不会等待,而是继续执行asyn ...

  6. org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL

    [报错] org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XM ...

  7. python基础--模块使用

      一:模块介绍 模块分为三种: 自定义模块 内置标准模块(又称标准库) 开源模块 自定义模块使用 # -*- coding:utf-8 -*- __author__ = 'shisanjun' &q ...

  8. 使用VSCode创建.NET Core 项目,添加类库间引用

    注:网络上搜索到的关于VsCode创建调试.Net Core 项目的文章都比较老旧,不能完全参考使用,根据网络文章.微软官方文档的指导下,学习并整理此文档,但也大体和文档学习路线相似,主要为记录学习过 ...

  9. Exception in thread "main" java.net.SocketTimeoutException: connect timed ou错误处理

    今天做了一个Jsoup解析网站的项目,使用Jsoup.connect(url).get()连接某网站时偶尔会出现java.net.SocketTimeoutException:Read timed o ...

  10. Java日期和时间

    目录 Java 日期和时间 Java 日期和时间 学习自 http://blog.csdn.net/zjf280441589/article/details/50447533 Date类 Date 类 ...