有没有一种高性能的方法来替换 .NET5 中的 BinaryFormatter? [英] Is there a high performance way to replace the BinaryFormatter in .NET5?

查看:28
本文介绍了有没有一种高性能的方法来替换 .NET5 中的 BinaryFormatter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 .NET5 之前,我们通过以下代码序列化/反序列化字节/对象:

Before .NET5 we serialize/deserialize the Bytes/Object by these code:

    private static byte[] StructToBytes<T>(T t)
    {
        using (var ms = new MemoryStream())
        {
            var bf = new BinaryFormatter();
            bf.Serialize(ms, t);
            return ms.ToArray();
        }
    }

    private static T BytesToStruct<T>(byte[] bytes)
    {
        using (var memStream = new MemoryStream())
        {
            var binForm = new BinaryFormatter();
            memStream.Write(bytes, 0, bytes.Length);
            memStream.Seek(0, SeekOrigin.Begin);
            var obj = binForm.Deserialize(memStream);
            return (T)obj;
        }
    }

但出于安全原因,BinaryFormatter 将被删除:

But the BinaryFormatter will be removed for the security reason:

https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/binaryformatter-security-guide

那么是否有一些简单但高性能的方法来替代 BinaryFormatter?

So is there some simple but high performance method to replace BinaryFormatter?

推荐答案

在我最近从 .NET Core 3.1 迁移到 .NET 5 的项目中,我用 Protobuf-net 替换了我们的 BinarySerializer 代码:https://github.com/protobuf-net/protobuf-net

In my project, which we recently migrated from .NET Core 3.1 to .NET 5, I swapped out our BinarySerializer code with Protobuf-net: https://github.com/protobuf-net/protobuf-net

代码几乎完全相同,并且该项目在 GitHub 上享有(目前)2200 万次下载和 320 万颗星的声誉.它非常快,并且没有围绕 BinarySerializer 的安全包袱.

The code was almost exactly the same, and the project is very reputable with (currently) 22 million downloads and 3.2k stars on GitHub. It is very fast and has none of the security baggage surrounding BinarySerializer.

这是我的 byte[] 序列化类:

Here's my class for byte[] serialization:

public static class Binary
{
    /// <summary>
    /// Convert an object to a Byte Array, using Protobuf.
    /// </summary>
    public static byte[] ObjectToByteArray(object obj)
    {
        if (obj == null)
            return null;

        using var stream = new MemoryStream();

        Serializer.Serialize(stream, obj);

        return stream.ToArray();
    }

    /// <summary>
    /// Convert a byte array to an Object of T, using Protobuf.
    /// </summary>
    public static T ByteArrayToObject<T>(byte[] arrBytes)
    {
        using var stream = new MemoryStream();

        // Ensure that our stream is at the beginning.
        stream.Write(arrBytes, 0, arrBytes.Length);
        stream.Seek(0, SeekOrigin.Begin);

        return Serializer.Deserialize<T>(stream);
    }
}

我确实必须向我序列化的类添加属性.它只用 [Serializable] 装饰,虽然我知道 Protobuf 可以处理很多常见的装饰,但那个不起作用.来自 github 上的示例:

I did have to add attributes to the class I serialized. It was decorated with [Serializable] only, and although I understand Protobuf can work with a lot of common decorations, that one didn't work. From the example on github:

[ProtoContract]
class Person {
    [ProtoMember(1)]
    public int Id {get;set;}
    [ProtoMember(2)]
    public string Name {get;set;}
    [ProtoMember(3)]
    public Address Address {get;set;}
}

[ProtoContract]
class Address {
    [ProtoMember(1)]
    public string Line1 {get;set;}
    [ProtoMember(2)]
    public string Line2 {get;set;}
}

就我而言,我在 Redis 中缓存内容,而且效果很好.

In my case I am caching things in Redis, and it worked great.

也可以在您的 .csproject 文件中重新启用此功能:

It is also possible to re-enable this, in your .csproject file:

<PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>

...但这是个坏主意.BinaryFormatter 对 .NET 的许多历史漏洞负责,而且无法修复.它可能会在 .NET 的未来版本中完全不可用,因此更换它是正确的做法.

...But it's a bad idea. BinaryFormatter is responsible for many of .NET's historical vulnerabilities, and it can't be fixed. It will likely become completely unavailable in future versions of .NET, so replacing it is the right move.

这篇关于有没有一种高性能的方法来替换 .NET5 中的 BinaryFormatter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆