Files
Obsidian_Unity/Unity学习/数据持久化/数据持久化之二进制.md
T
2026-05-03 14:06:26 +08:00

4.2 KiB
Raw Blame History

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 在反序列化时可能存在安全漏洞,不适合用于处理不受信任的数据。

  • 替代方案

    • 文本序列化(如 JsonSerializerXmlSerializer

    • 跨平台高性能方案(如 MessagePackProtobuf


6. 总结

  • 文件流序列化:直接将对象保存到磁盘文件中。

  • 内存流序列化:对象 → 字节数组 → 可保存或传输。

  • 反序列化:根据文件流或字节数组还原对象。

序列化与反序列化是 C# 中对象持久化与数据传输的核心知识点,实际开发中需结合安全性与场景选择合适的序列化方式。