以二进制,打包格式序列化结构
在C#中是否有一种方法可以将结构序列化为二进制流(MemoryStream),这样二进制表示等同于结构在视觉上的布局方式(即没有填充)?
在C / C ++中,您使用#pragma命令告诉编译器打包结构,以便字段之间没有填充。 如果您有两个应用程序通过套接字来回传递消息,这将非常有用。 禁用打包后,您可以简单地通过套接字“发送”结构的内容,而不必担心将每个字段单独打包到二进制缓冲区中(如果需要,还必须进行字节顺序交换)。
除非您使用不安全的代码。 使用Protocol Buffers或Thrift或类似的东西; 我不建议根据我的经验使用.NET内置二进制序列化。 您还可以使用BinaryWriter/BinaryReader
序列化/反序列化(使用reflection或预生成序列化代码)。 至于打包,您可以使用[StructLayout]
属性控制它。
您可以使用[StructLayout]
和[FieldOffset]
属性来控制结构字段的打包方式(google’marshalling’以获取更多信息),然后使用以下内容生成结构的二进制表示forms,可以通过您的结构发送网络流:
public static byte[] GetBytes(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
- 您需要非托管代码权限
- 缓冲区固定可能会影响性能
- 您的结构不能有引用(字符串和数组有特殊情况)