1

こんにちは私は次のような構造を持っています

    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 全体を 1 バイト配列 [] に変換する便利な方法はありますか?

4

3 に答える 3

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;
    }
}
于 2013-01-08T02:43:04.353 に答える
0

それを行うには多くの方法がありますが、すべての方法でフィールドごとにバイトをプルする必要があります。

ここに1つあります:

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.BlockCopyまたはを使用することもできますArray.Copy

于 2013-01-08T02:44:58.970 に答える
0

各バイト配列は実際にはバイト配列への参照を格納しているため、直接単一の配列ではありません。

このデータから単一の配列を作成する必要があります。個人的には、これを行うメソッドを作成しbyte[]、適切な長さの結果を作成してから、 Array.Copyを使用して結果の配列にコピーします。

于 2013-01-08T02:28:46.413 に答える