C#中有一种方法可以将结构序列化为二进制流(MemoryStream),以便二进制表示等同于结构在视觉上是如何布局的(即无填充)?以二进制序列化结构,压缩格式
在C/C++中,您可以使用#pragma命令来告诉编译器打包结构,以便字段之间没有填充。如果您有两个应用程序通过套接字来回传递消息,这会很有帮助。在封装禁用的情况下,您可以简单地将结构的内容“发送”到套接字上,而不必担心将每个字段单独封装到二进制缓冲区中(还必须在必要时进行字节顺序交换)。
C#中有一种方法可以将结构序列化为二进制流(MemoryStream),以便二进制表示等同于结构在视觉上是如何布局的(即无填充)?以二进制序列化结构,压缩格式
在C/C++中,您可以使用#pragma命令来告诉编译器打包结构,以便字段之间没有填充。如果您有两个应用程序通过套接字来回传递消息,这会很有帮助。在封装禁用的情况下,您可以简单地将结构的内容“发送”到套接字上,而不必担心将每个字段单独封装到二进制缓冲区中(还必须在必要时进行字节顺序交换)。
除非您使用不安全的代码,否则不会。使用Protocol Buffers或Thrift或类似的东西;根据我的经验,我不会推荐.NET内置二进制序列化。您也可以使用BinaryWriter/BinaryReader
(使用反射或预生成序列化代码)来序列化/反序列化。至于包装,您可以使用[StructLayout]
属性来控制它。
您可以使用[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;
}
的缺点:
对于信息 - protobuf网不支持结构(只有类),和我很确定dotnet-protobufs也不是。我不知道节俭。 – 2009-05-03 19:02:04