以二进制,打包格式序列化结构

时间:2009-05-03 18:26:47

标签: c# .net serialization

在C#中是否有一种方法可以将结构序列化为二进制流(MemoryStream),这样二进制表示等同于结构在视觉上的布局方式(即没有填充)?

在C / C ++中,您使用#pragma命令告诉编译器打包结构,以便字段之间没有填充。如果您有两个应用程序通过套接字来回传递消息,这将非常有用。禁用打包后,您可以简单地通过套接字“发送”结构的内容,而不必担心将每个字段单独打包到二进制缓冲区中(如果需要,还必须进行字节顺序交换)。

2 个答案:

答案 0 :(得分:2)

除非您使用不安全的代码。使用Protocol Buffers或Thrift或类似的东西;我不建议根据我的经验使用.NET内置二进制序列化。您还可以使用BinaryWriter/BinaryReader序列化/反序列化(使用反射或预生成序列化代码)。至于打包,您可以使用[StructLayout]属性控制它。

答案 1 :(得分:1)

您可以使用[StructLayout][FieldOffset]属性来控制结构字段的打包方式(google'marshalling'以获取更多信息),然后使用以下内容生成您的二进制表示形式可以通过网络流发送的结构:

public static byte[] GetBytes<TStruct>(TStruct data) where TStruct : struct
{
    int structSize = Marshal.SizeOf(typeof(TStruct));
    byte[] buffer = new byte[structSize];
    GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
    Marshal.StructureToPtr(data, handle.AddrOfPinnedObject(), false);
    handle.Free();
    return buffer;
}

缺点:

  • 它不是惯用的.NET
  • 您需要非托管代码权限
  • 缓冲区固定可能会影响性能
  • 您的结构不能有引用(字符串和数组有特殊情况)
相关问题