2013-01-08 40 views
1

嗨,我有一個結構如下結構字節字段整理爲byte []

private struct MessageFormat 
    { 
     public byte[] Header; //start of message 
     public byte Fragmentation; //single packet or not 
     public byte Encryption; //encrypted message 
     public byte[] Authentication; //password 
     public byte[] Flag; //to locate end of auth 
     public byte[] Data; //info 
     public byte[] Trailer; //end of message 
    } 

是有整個的MessageFormat轉換成一個字節數組[後,我填寫的所有字段]一種方便的方法?

+0

嘗試查找BitArray類。 –

+0

有一個方便的方法,但你可能不會喜歡它。 .NET框架方式煩惱了很多,確保byte []可以安全地轉換回原始對象。不太方便的方法是BinaryWriter。 –

回答

0

我寫了一個示例代碼,它將完全按照您的要求進行操作。它結合了Reflection和Buffer.BlockCopy,但它可以做得更多的表現(例如提前裝箱format,避免匿名類型 - 以及它們在示例中的尷尬,冗餘初始化 - 甚至根本不使用Reflection和硬編碼序列化方法)。請注意,我提供的方法不會爲結果使用緩衝區,但會在分配數組之前計算最終長度。

var format = new MessageFormat 
{ 
    //Initialize your format 
}; 
//Gets every instance public field in the type 
//Expects it to be either byte, either byte[] 
//Extracts value, length and type 
var fields = typeof (MessageFormat).GetFields(). 
    Select(f => f.GetValue(format)). 
    Select(v => new 
    { 
     Value = v, 
     Type = v is byte ? typeof (byte) : typeof (byte[]), 
     Length = v is byte ? 1 : (v as byte[]).Length 
    }). 
    ToArray(); 
//Calculates the resulting array's length 
var totalLength = fields.Sum(v => v.Length); 
var bytes = new byte[totalLength]; 
var writingIndex = 0; 
foreach (var field in fields) 
{ 
    //If the field is a byte, write at current index, 
    //then increment the index 
    if (field.Type == typeof (byte)) 
     bytes[writingIndex++] = (byte) field.Value; 
    else 
    { 
     //Otherwise, use a performant memory copy method 
     var source = field.Value as byte[]; 
     var sourceLength = source.Length; 
     Buffer.BlockCopy(source, 0, bytes, writingIndex, sourceLength); 
     writingIndex += sourceLength; 
    } 
} 
0

每個字節數組實際上都存儲着對字節數組的引用,所以它不是直接的單個數組。

您需要從這些數據中構建一個數組。我會親自制定方法來執行此操作,創建適當長度的結果byte[],然後使用Array.Copy將其複製到結果數組中。

0

許多方法來做到這一點,但他們都需要拉字節的字段字段。

這裏有一個:

var msg = new MessageFormat(); 
var arr = new byte[msg.Header.Length + 1 + 1 + msg.Authentication.Length + msg.Flag.Length + msg.Data.Length + msg.Trailer.Length]; 
using (var stream = new MemoryStream(arr, 0, arr.Length, true)) 
{ 
    stream.Write(msg.Header, 0, msg.Header.Length); 
    stream.WriteByte(msg.Fragmentation); 
    stream.WriteByte(msg.Encryption); 
    stream.Write(msg.Authentication, 0, msg.Authentication.Length); 
    stream.Write(msg.Flag, 0, msg.Flag.Length); 
    stream.Write(msg.Data, 0, msg.Data.Length); 
    stream.Write(msg.Trailer, 0, msg.Trailer.Length); 
} 

你也可以使用Buffer.BlockCopyArray.Copy