如何解决是否有一些高性能可以替代.NET5中的BinaryFormatter?
在.NET5之前,我们通过以下代码对字节/对象进行序列化/反序列化:
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,bytes.Length);
memStream.Seek(0,SeekOrigin.Begin);
var obj = binForm.Deserialize(memStream);
return (T)obj;
}
}
但是出于安全原因,将删除BinaryFormatter:
https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/binaryformatter-security-guide
那么有什么简单但高性能的方法可以替换BinaryFormatter?
解决方法
在我最近从.NET Core 3.1迁移到.NET 5的项目中,我用Protobuf-net交换了BinarySerializer代码:https://github.com/protobuf-net/protobuf-net
代码几乎完全相同,并且该项目在GitHub上(目前)有2200万次下载和3.2k星,因此享有盛誉。它非常快速,并且BinarySerializer周围没有安全行李。
这是我的byte []序列化课程:
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,arrBytes.Length);
stream.Seek(0,SeekOrigin.Begin);
return Serializer.Deserialize<T>(stream);
}
}
我确实必须向序列化的类添加属性。它仅用[Serializable]装饰,尽管我了解Protobuf可以使用许多常见的装饰,但没有用。来自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中缓存内容,效果很好。
还可以在您的.csproject文件中重新启用它:
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
...但这是一个坏主意。 BinaryFormatter负责.NET的许多历史漏洞,因此无法修复。在将来的.NET版本中,它可能会变得完全不可用,因此替换它是正确的选择。
,如果您使用 .NET Core 5 或更高版本,您可以像这样使用新的 System.Text.Json.JsonSerializer.Serialize 和 System.Text.Json.JsonSerializer.Deserialize:
public static class Binary
{
/// <summary>
/// Convert an object to a Byte Array.
/// </summary>
public static byte[] ObjectToByteArray(object objData)
{
if (objData == null)
return default;
return Encoding.UTF8.GetBytes(JsonSerializer.Serialize(objData,GetJsonSerializerOptions()));
}
/// <summary>
/// Convert a byte array to an Object of T.
/// </summary>
public static T ByteArrayToObject<T>(byte[] byteArray)
{
if (byteArray == null || !byteArray.Any())
return default;
return JsonSerializer.Deserialize<T>(byteArray,GetJsonSerializerOptions());
}
private static JsonSerializerOptions GetJsonSerializerOptions()
{
return new JsonSerializerOptions()
{
PropertyNamingPolicy = null,WriteIndented = true,AllowTrailingCommas = true,DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,};
}
}
,
在.NET Core 5中可以使用它:
只需添加
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
对于这样的项目:
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>
我相信它会起作用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。