You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework 4.7.2中BinaryFormatter的二进制读写替代方案

.NET Framework 4.7.2下替代BinaryFormatter的二进制读写方案

原代码依赖BinaryFormatter完成ConcurrentDictionary<string, DateTime>的序列化与反序列化,但BinaryFormatter存在严重安全风险,以下是几种适配.NET Framework 4.7.2的替代方案:

方案1:手动基于BinaryWriter/BinaryReader实现

完全原生无依赖,可控性强,安全性高,适合简单类型的序列化场景。

序列化代码

private const string BINARY_FILENAME = "jobsAck.dat";
private ConcurrentDictionary<string, DateTime> _jobsAck;

public void SaveToDisk()
{
    using (var stream = File.Open(BINARY_FILENAME, FileMode.Create))
    using (var writer = new BinaryWriter(stream))
    {
        // 先写入键值对总数
        writer.Write(_jobsAck.Count);
        foreach (var pair in _jobsAck)
        {
            writer.Write(pair.Key);
            // 将DateTime转为Ticks存储,保证二进制兼容性
            writer.Write(pair.Value.Ticks);
        }
    }
}

反序列化代码

public void LoadFromDisk()
{
    if (!File.Exists(BINARY_FILENAME))
    {
        _jobsAck = new ConcurrentDictionary<string, DateTime>();
        return;
    }

    using (var stream = File.Open(BINARY_FILENAME, FileMode.Open, FileAccess.Read))
    using (var reader = new BinaryReader(stream))
    {
        var count = reader.ReadInt32();
        var tempDict = new Dictionary<string, DateTime>(count);
        for (int i = 0; i < count; i++)
        {
            var key = reader.ReadString();
            var ticks = reader.ReadInt64();
            tempDict[key] = new DateTime(ticks);
        }
        _jobsAck = new ConcurrentDictionary<string, DateTime>(tempDict);
    }
}

方案2:使用DataContractSerializer(原生序列化器)

DataContractSerializer是.NET官方提供的安全序列化器,支持强类型校验,无需第三方依赖。

序列化代码

using System.Runtime.Serialization;
using System.Xml;

public void SaveToDisk()
{
    // 转成普通Dictionary提升兼容性
    var dict = new Dictionary<string, DateTime>(_jobsAck);
    var serializer = new DataContractSerializer(typeof(Dictionary<string, DateTime>));
    using (var stream = File.Open(BINARY_FILENAME, FileMode.Create))
    using (var writer = XmlDictionaryWriter.CreateBinaryWriter(stream))
    {
        serializer.WriteObject(writer, dict);
    }
}

反序列化代码

public void LoadFromDisk()
{
    if (!File.Exists(BINARY_FILENAME))
    {
        _jobsAck = new ConcurrentDictionary<string, DateTime>();
        return;
    }

    var serializer = new DataContractSerializer(typeof(Dictionary<string, DateTime>));
    using (var stream = File.Open(BINARY_FILENAME, FileMode.Open, FileAccess.Read))
    using (var reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
    {
        var dict = serializer.ReadObject(reader) as Dictionary<string, DateTime>;
        _jobsAck = dict != null ? new ConcurrentDictionary<string, DateTime>(dict) : new ConcurrentDictionary<string, DateTime>();
    }
}

方案3:使用Protobuf-Net(第三方高性能序列化库)

基于Google Protocol Buffers实现,序列化后体积小、速度快,安全性高,需通过NuGet安装protobuf-net包适配.NET Framework 4.7.2。

序列化代码

using ProtoBuf;

public void SaveToDisk()
{
    // 转普通Dictionary简化序列化逻辑
    var dict = new Dictionary<string, DateTime>(_jobsAck);
    using (var stream = File.Open(BINARY_FILENAME, FileMode.Create))
    {
        Serializer.Serialize(stream, dict);
    }
}

反序列化代码

public void LoadFromDisk()
{
    if (!File.Exists(BINARY_FILENAME))
    {
        _jobsAck = new ConcurrentDictionary<string, DateTime>();
        return;
    }

    using (var stream = File.Open(BINARY_FILENAME, FileMode.Open, FileAccess.Read))
    {
        var dict = Serializer.Deserialize<Dictionary<string, DateTime>>(stream);
        _jobsAck = new ConcurrentDictionary<string, DateTime>(dict);
    }
}

内容的提问来源于stack exchange,提问作者Vivek Nuna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:47:10