【发布时间】:2019-05-29 05:10:41
【问题描述】:
我正在编写一个优化的二进制读取器/写入器,用于我自己的学习目的。一切正常,直到我编写了decimals 的编码和解码测试。我的测试还包括 .NET Framework 的 BinaryWriter 是否为我的 BinaryWriter 产生兼容的输出,反之亦然。
我主要使用不安全和指针将变量写入字节数组。这些是通过指针和BinaryWriter 写入小数时的结果:
BinaryWriter....: E9 A8 94 23 9B CA 4E 44 63 C5 44 39 00 00 1A 00
unsafe *decimal=: 00 00 1A 00 63 C5 44 39 E9 A8 94 23 9B CA 4E 44
我编写小数的代码如下所示:
unsafe
{
byte[] data = new byte[16];
fixed (byte* pData = data)
*(decimal*)pData = 177.237846528973465289734658334m;
}
而使用 .NET Framework 的 BinaryWriter 看起来像这样:
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(ms))
writer.Write(177.237846528973465289734658334m);
ms.ToArray();
}
Microsoft 使他们的 BinaryWriter 与 decimals 在内存中的存储方式不兼容。通过查看参考源,我们看到微软使用了一个名为 GetBytes 的内部方法,这意味着 GetBytes 的输出与 decimals 在内存中的存储方式不兼容。
微软以这种方式实现写入decimals 有什么原因吗?使用unsafe 的方式来实现自己的二进制格式或协议会不会很危险,因为将来小数的内部布局可能会发生变化?
使用unsafe 方式比使用BinaryWriter 调用的GetBytes 方式执行得更好。
【问题讨论】:
-
@GSerg 公平地说,引用的答案只是说它是.NET 特定格式。它并没有真正回答 OP 的问题。
-
@Neijwiert 好吧,没有人可以回答 OP 的问题,即微软是否会愿意改变这种格式。出于兼容性原因,我们只能推测这是极不可能的。
-
@GSerg 是的,但我有点希望有人解释当前的实现是如何完成的,因为我不能。
-
@Neijwiert 请参阅second answer。
decimal --> decimal.GetBytes(), 16 bytes, should see the System.Decimal class code。这是一个错字,应该是GetBits()。
标签: c# decimal unsafe binarywriter