Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Binary Serialization và Deserialization trong C#: Hướng dẫn chi tiết

Khái niệm

  • Binary Serialization: Chuyển đổi object thành định dạng nhị phân (không đọc được bằng mắt thường).
  • Deserialization: Chuyển đổi ngược từ nhị phân về object gốc.

Đặc điểm Binary Serialization

Đặc điểmMô tả
Định dạngNhị phân (binary), compact, nhanh
Đọc được bởi ngườiKhông
Kích thướcNhỏ hơn XML/JSON
Hiệu năngRất nhanh
Type fidelityGiữ toàn bộ type info (private fields, assembly version)
Bảo mậtKhông an toàn cho untrusted data (có thể execute code)

Thư viện sử dụng

⚠️ Lưu ý quan trọng: BinaryFormatter đã bị deprecated ( obsoleted ) từ .NET 5+ và bị loại bỏ hoàn toàn từ .NET 8+ do lỗ hổng bảo mật nghiêm trọng (CVE-2023-XXXX).

Cách cũ (Legacy - .NET Framework / .NET Core 3.1)

using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

[Serializable]
public class Demo 
{
    public string ApplicationName { get; set; } = "Binary Serialize";
    public int ApplicationId { get; set; } = 1001;
}

class Program 
{
    static void Main() 
    {
        var sample = new Demo();
        
        // Serialize
        using (var fileStream = new FileStream(@"C:\Temp\Questions.dat", FileMode.Create))
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(fileStream, sample);
        }
        
        // Deserialize
        using (var fileStream = new FileStream(@"C:\Temp\Questions.dat", FileMode.Open))
        {
            var formatter = new BinaryFormatter();
            var deserialized = (Demo)formatter.Deserialize(fileStream);
            Console.WriteLine($"Name: {deserialized.ApplicationName}, Id: {deserialized.ApplicationId}");
        }
    }
}

Thay thế an toàn cho .NET 5+ (Modern Alternatives)

1. System.Text.Json (Khuyến nghị chính thức)

using System.Text.Json;

public class Demo 
{
    public string ApplicationName { get; set; } = "JSON Serialize";
    public int ApplicationId { get; set; } = 1001;
}

class Program 
{
    static void Main() 
    {
        var sample = new Demo();
        
        // Serialize to bytes (UTF-8)
        byte[] jsonBytes = JsonSerializer.SerializeToUtf8Bytes(sample);
        File.WriteAllBytes(@"C:\Temp\demo.json", jsonBytes);
        
        // Deserialize from bytes
        byte[] readBytes = File.ReadAllBytes(@"C:\Temp\demo.json");
        var deserialized = JsonSerializer.Deserialize<Demo>(readBytes);
        
        Console.WriteLine($"Name: {deserialized.ApplicationName}, Id: {deserialized.ApplicationId}");
    }
}

2. MessagePack (Hiệu năng cao, binary compact)


// NuGet: MessagePack
using MessagePack;

[MessagePackObject]
public class Demo 
{
    [Key(0)] public string ApplicationName { get; set; }
    [Key(1)] public int ApplicationId { get; set; }
}

class Program 
{
    static void Main() 
    {
        var sample = new Demo { ApplicationName = "MsgPack", ApplicationId = 2001 };
        
        // Serialize
        byte[] bytes = MessagePackSerializer.Serialize(sample);
        File.WriteAllBytes(@"C:\Temp\demo.msgpack", bytes);
        
        // Deserialize
        var deserialized = MessagePackSerializer.Deserialize<Demo>(File.ReadAllBytes(@"C:\Temp\demo.msgpack"));
    }
}

3. Protobuf (Google Protocol Buffers)


// NuGet: Google.Protobuf
// Cần file .proto định nghĩa schema
syntax = "proto3";
message Demo {
    string application_name = 1;
    int32 application_id = 2;
}

So sánh các phương án hiện đại

Phương ánĐịnh dạngHiệu năngKích thướcCross-platformSchema
System.Text.JsonText (UTF-8)CaoTrung bình✅Không cần
MessagePackBinaryRất caoNhỏ✅Attribute/Code-first
ProtobufBinaryRất caoRất nhỏ✅File .proto (Schema-first)
BinaryFormatterBinaryTrung bìnhTrung bình❌ (.NET only)Không cần

Best Practices

  • Không dùng BinaryFormatter cho dữ liệu không tin cậy (untrusted input).
  • Dùng System.Text.Json cho hầu hết trường hợp (web API, config, cache).
  • Dùng MessagePack/Protobuf cho high-performance, inter-service communication, gRPC.
  • Luôn versioning data: thêm [JsonPropertyName], [Key], optional fields.
  • Cân nhắc JsonSerializerOptions: PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true (debug).