2009-05-03 56 views
2

C#中有一种方法可以将结构序列化为二进制流(MemoryStream),以便二进制表示等同于结构在视觉上是如何布局的(即无填充)?以二进制序列化结构,压缩格式

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

回答

2

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

+0

对于信息 - protobuf网不支持结构(只有类),和我很确定dotnet-protobufs也不是。我不知道节俭。 – 2009-05-03 19:02:04

1

您可以使用[StructLayout][FieldOffset]属性来控制你的结构的域被打包的方式(谷歌“编组”获取更多信息),然后使用以下方法来生成你的结构的二进制表示,可以通过发送您网络流:

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
  • 您需要非托管代码权限
  • 缓冲钉扎可能会影响性能
  • 您的结构不能有引用(有特殊情况的字符串和数组)