Sea*_*man 4 .net c# serialization pointers unmanaged
我的问题是是否可以确定引用类型的序列化大小(以字节为单位)。
情况如下:
我使用 BinaryFormatter 类来序列化基本 .NET 类型,例如:
[Serializable]
public class Foo
{
public string Foo1 { get; set; }
public string Foo2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我将每个项目序列化为 byte[],然后将该段添加到现有 byte[] 的末尾,并在每个段的末尾添加回车符以分隔对象。
为了反序列化,我使用 Marshal.ReadByte() 如下:
List<byte> buffer = new List<byte>();
for (int i = 0; i < MapSize; i++)
{
byte b = Marshal.ReadByte(readPtr , i);
if (b != delim) // read until encounter a carriage return
buffer.Add(b);
else
break;
}
readPtr = readPtr + buffer.Count + 1; // incrementing the pointer for the next object
return buffer.ToArray();
Run Code Online (Sandbox Code Playgroud)
我相信使用 Marshal.Copy() 会更有效,但我需要提前知道序列化字节段的长度。有没有一种方法可以从正在序列化的类型可靠地计算出这个值,或者我可以使用一种整体更有效的方法?
此外,最终使用回车符也是不可靠的。所以我想知道是否有更标准的方法来分隔对象,无论是通过自定义 BinaryFormatter 还是使用其他标准化最佳实践?例如,如果 BinaryFormatter 序列化为通用 List<>,则 BinaryFormatter 是否有一种特定的方式来分隔对象?
没有一个非常好的方法来预先确定序列化长度。BinaryFormatter 协议的规范可在此处获取: http://msdn.microsoft.com/en-us/library/cc236844 (v=prot.10).aspx
我将省去您为了您的目的而阅读它的麻烦:
如果您想要一种简单的方法来完成任务,只需创建一个包含所有对象的数组并序列化该单个数组即可。这可以解决您的大部分问题。界定不同对象的所有问题均由 BinaryFormatter 处理。你不会有过多的内存复制。最终的输出将更加紧凑,因为 BinaryFormatter 每次调用只需指定一次字段名称。
最后,我可以告诉您,额外的内存副本并不是当前实现效率低下的主要根源。BinaryFormatter 对反射的使用以及它对序列化输出中的字段名称进行编码的事实使您的效率大大降低。
如果效率至关重要,那么我建议编写一些自定义代码,以“纯旧数据”格式对结构的内容进行编码。然后您就可以控制写入的数量和方式。