4.2 KiB
C# 对象的序列化与反序列化
1. 什么是序列化?
序列化(Serialization) 是指将对象的状态信息转换为可以存储或传输的形式(例如字节流、文件、内存数据)的过程。
反之,反序列化(Deserialization) 则是将存储或传输的序列化数据还原为对象的过程。
在 C# 中,最常用的方式是通过 BinaryFormatter 类来完成二进制序列化与反序列化。
2. 核心类与方法
-
BinaryFormatter.Serialize(Stream, object)
将对象序列化到指定的流中。 -
BinaryFormatter.Deserialize(Stream)
从指定的流中反序列化对象。
⚠️ 注意:从 .NET 5 开始,官方已经不推荐使用
BinaryFormatter(存在安全风险),更推荐System.Text.Json或XmlSerializer等。但在学习和理解基础时,仍可使用。
3. 序列化方式
3.1 文件流方式
通过 文件流(FileStream) 将对象直接保存到文件中。
csharp
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable] // 必须标记为可序列化
public class Person
{
public string Name;
public int Age;
}
class Program
{
static void Main()
{
Person p = new Person { Name = "Tom", Age = 25 };
// 序列化到文件
using (FileStream fs = new FileStream("person.dat", FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, p);
}
Console.WriteLine("对象已序列化到文件 person.dat");
}
}
3.2 内存流方式
通过 内存流(MemoryStream) 将对象序列化成字节数组,便于网络传输或自定义存储。
csharp
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Person
{
public string Name;
public int Age;
}
class Program
{
static void Main()
{
Person p = new Person { Name = "Alice", Age = 30 };
byte[] buffer;
// 序列化到内存流
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, p);
buffer = ms.ToArray(); // 获取字节数组
}
// 可以将字节数组写入文件或通过网络传输
File.WriteAllBytes("person_bytes.dat", buffer);
Console.WriteLine("对象已序列化为字节数组并写入 person_bytes.dat");
}
}
4. 反序列化
4.1 从文件反序列化
csharp
using (FileStream fs = new FileStream("person.dat", FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
Person p = (Person)formatter.Deserialize(fs);
Console.WriteLine($"Name: {p.Name}, Age: {p.Age}");
}
4.2 从字节数组反序列化
csharp
byte[] buffer = File.ReadAllBytes("person_bytes.dat");
using (MemoryStream ms = new MemoryStream(buffer))
{
BinaryFormatter formatter = new BinaryFormatter();
Person p = (Person)formatter.Deserialize(ms);
Console.WriteLine($"Name: {p.Name}, Age: {p.Age}");
}
5. 注意事项
-
必须添加
[Serializable]特性
否则对象无法被序列化。 -
字段级别的控制
如果某些字段不想被序列化,可以使用[NonSerialized]特性修饰。
csharp
[NonSerialized]
private string password;
-
安全问题
BinaryFormatter在反序列化时可能存在安全漏洞,不适合用于处理不受信任的数据。 -
替代方案
-
文本序列化(如
JsonSerializer、XmlSerializer) -
跨平台高性能方案(如
MessagePack、Protobuf)
-
6. 总结
-
文件流序列化:直接将对象保存到磁盘文件中。
-
内存流序列化:对象 → 字节数组 → 可保存或传输。
-
反序列化:根据文件流或字节数组还原对象。
序列化与反序列化是 C# 中对象持久化与数据传输的核心知识点,实际开发中需结合安全性与场景选择合适的序列化方式。