我有一个文件,我正在使用下面的 C# 代码编写内容。
ConcurrentDictionary<string, DateTime> _jobsAck;
public void SaveToDisk()
{
var binaryFormatter = new BinaryFormatter();
using (var stream = File.Open(BINARY_FILENAME, FileMode.OpenOrCreate))
{
binaryFormatter.Serialize(stream, _jobsAck);
}
}
我正在阅读此文件并使用下面的 C# 代码进行反序列化。
public void LoadFromDisk()
{
if (!File.Exists(BINARY_FILENAME)) return;
var binaryFormatter = new BinaryFormatter();
using (var stream = File.Open(BINARY_FILENAME, FileMode.Open, FileAccess.Read))
{
var deserializedStream = binaryFormatter.Deserialize(stream);
_jobsAck = deserializedStream as ConcurrentDictionary<string, DateTime>;
if (_jobsAck == null)
{
_jobsAck = new ConcurrentDictionary<string, DateTime>();
if (!(deserializedStream is Dictionary<string, DateTime> ackDict)) return;
foreach (var pair in ackDict)
{
_jobsAck.TryAdd(pair.Key, pair.Value);
}
}
}
}
我们被要求不要使用 BinaryFormatter,因为它存在一些与安全相关的问题。那么有没有其他方法可以以二进制格式读/写?
.Net框架版本:4.7.2
如果您的客户已经使用 binaryFormatter 保存了数据,您需要保留它以用于读取文件,无论其安全问题如何,直到您将所有或大多数客户迁移到某种新格式为止。据我所知,没有发布 BinaryFormatter 格式的规范,也没有任何其他兼容库。即使在那里,我也不确定它可以解决安全问题,因为这些问题是格式本身固有的。
所以第一步应该是创建一种新格式,使用一些设计良好的序列化库。我主要使用 json 和 protobuf (.net),但是有很多好的替代方案,如果您需要建议,请参阅 https://softwarerecs.stackexchange.com/。几乎任何东西都应该比 BinaryFormatter 更好。
然后您应该更新您的应用程序,以便它不能再使用binaryFormtter 保存文件,而只能以您的新格式保存文件。根据您的具体用例,您可能能够在安装新版本后立即转换保存的数据,在其他情况下,您可能只能在用户明确保存文件时才能执行此操作。
支持新格式的更新应用程序发布一段时间后,您可以开始考虑删除对 BinaryFormatter 的支持。旧版本的用户可能被迫更新到中间版本并转换其文件。或者您可以发布一个单独的工具,仅在旧格式和新格式之间进行转换。您还可以在以旧格式打开文件时添加安全警告,至少警告用户存在风险。
这里的要点是,越早引入新格式,就越早放弃对旧格式的支持。此过程的长度在很大程度上取决于您对客户的支持承诺以及做出突破性改变的意愿。
我创建了一个二进制序列化 alternative,它与
IFormatter
基础设施完全兼容,包括 ISerializable
、IDeserializationCallback
、IObjectReference
接口、(反)序列化事件方法、代理选择器和绑定器。
另请注意,在安全模式下,即将推出的版本将🔐 安全注意事项: 请阅读
BinarySerializationFormatter
课程的备注部分的安全注意事项。即使启用了(这消除了SafeMode
遭受的许多安全问题),如果反序列化被序列化为递归对象图的类型,即不能完全安全。依赖于BinaryFormatter
IFormatter
基础设施。
引入更多限制。
您可以在这里找到 NuGet 包和在线演示这里,它还演示了与 BinaryFormatter
相比结果有多紧凑。