2009-05-03 55 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
  • 您需要非託管代碼權限
  • 緩衝釘扎可能會影響性能
  • 您的結構不能有引用(有特殊情況的字符串和數組)