C#序列化与反序列化

时间:2021-07-28 23:49:15

  序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。两个过程结合可以存储和传输数据。

  .NET Framework 提供两种序列化技术:

  1) 二进制序列化
  这种序列化可以保持类型不变,即可以在应用程序的不同调用之间保留对象的状态。
  2)XML 和SOAP 序列化
  这种序列化仅序列化公共属性和字段,不保存类型。

  另外还有Json序列化,需要引用Newtonsoft.Json

1 二进制序列化与反序列化

  序列化可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确副本。

  序列化有两个最重要的功能:一个时将对象的状态保持在存储媒体中,以便可以在以后重新创建精确的副本;另一个是通过值将对象从一个应用程序域发送到另有一个应用程序域中。例如,序列化可用于在ASP.NET中保存会话状态并将对象复制到Windows窗体的剪贴板中。远程处理还可以试用序列化通过将对象从一个程序域传递到另一个应用程序域中。

1.1 序列化

  序列化一个类最简单的方式是试用如下所示的Serializable属性标记。

[Serializable] public class AuthUserEntry { private string accountName; private int accountId; public string AccountName { } public int AccountId { } } }

  下面用代码演示该类的实例是如何被序列化到一个二进制文件(.bin)中的。

AuthUserEntry user = new AuthUserEntry(); user.AccountId = 9912053; user.AccountName = "XinXin"; IFormatter formater = new BinaryFormatter(); Stream stream = new FileStream("UserInfo.bin", FileMode.Create, FileAccess.Write, FileShare.None); formater.Serialize(stream, user); stream.Close();

  在这段代码中,创建流的实例和试用的格式接口后,对该格式接口调用Serialize方法,类中的所有成员变量都将被序列化,即使是哪些已被标记为私有的变量。

1.2 反序列化

  要将对象还原回其以前的状态,首先,创建用于读取的流和格式化接口,然后用格式化接口反序列化该对象。下面的代码示例说明如何执行上述的操作

IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("UserInfo.bin", FileMode.Open, FileAccess.Read, FileShare.Read); AuthUserEntry me = (AuthUserEntry) formatter.Deserialize(stream); stream.Close();

  需要特别注意的是,在反序列化一个对象时不调用构造函数。

  【例】二进制序列化和反序列化的方法

using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace BinarySerializableExample { [Serializable] public class AuthUserEntry { private string accountName; private int accountId; public string AccountName { get { return accountName; } set { accountName = value; } } public int AccountId { get { return accountId; } set { accountId = value; } } } class Account { static void Main(string[] args) { AuthUserEntry user = new AuthUserEntry(); user.AccountId = 9912053; user.AccountName = "XinXin"; IFormatter formater = new BinaryFormatter(); Stream stream = new FileStream("UserInfo.bin", FileMode.Create, FileAccess.Write, FileShare.None); formater.Serialize(stream, user); stream.Close(); stream = new FileStream("UserInfo.bin", FileMode.Open, FileAccess.Read, FileShare.Read); AuthUserEntry me = (AuthUserEntry)formater.Deserialize(stream); stream.Close(); Console.WriteLine("帐户号:{0}", me.AccountId); Console.WriteLine("帐户名:{0}", me.AccountName); //按回车键结束 Console.ReadLine(); } } }

  输出结果为:

    账号名:9912053

    账户名:XinXin

  打开应用程序的bin文件夹,会看到有一个生成文件UserInfo.bin,打开它会看到正是AuthUserEnty对象实例的值。

1.3 有选择的序列化