0 から始まらないバッファに対して GetBytes を実行する、より苦痛の少ない方法はありますか?

StackOverflow https://stackoverflow.com/questions/2527018

  •  22-09-2019
  •  | 
  •  

質問

プロジェクトで生のバイトを処理する必要があり、基本的に次のようなことを行う必要があります

byte[] ToBytes(){
  byte[] buffer=new byte[somelength];
  byte[] tmp;
  tmp=BitConverter.GetBytes(SomeShort);
  buffer[0]=tmp[0];
  buffer[1]=tmp[1];
  tmp=BitConverter.GetBytes(SomeOtherShort);
  buffer[2]=tmp[0];
  buffer[3]=tmp[1];
}

これはとても間違っていると感じていますが、それを行うより良い方法が見つかりません。もっと簡単な方法はありますか?

役に立ちましたか?

解決

BinaryWriter非常に効率的である。

    byte[] ToBytes() {
        var ms = new MemoryStream(somelength);
        var bw = new BinaryWriter(ms);
        bw.Write(SomeShort);
        bw.Write(SomeOtherShort);
        return ms.ToArray();
    }

他のヒント

あなたは新しい配列にtmpを初期化する必要はありません。 BitConverter.GetBytesは、新しい配列を作成し、あなたのためにそれを返します。そこにはGetBytesについてできることはあまりないのですが、あなたはのようなメソッドを使用することができますBuffer.BlockCopy のコピー操作を簡素化する。

あなたは、コードのパフォーマンスが重要な作品でこれをやっていない場合、あなたは少しLINQyを行って、同じようなことを行うことができます:

IEnumerable<byte> bytes = BitConverter.GetBytes(first);
bytes = bytes.Concat(BitConverter.GetBytes(second));
bytes = bytes.Concat(BitConverter.GetBytes(third));
// ... so on; you can chain the calls too
return bytes.ToArray();
あなたは(値タイプのセットを持っている)事前にサイズを知っている場合は、

あなたは構造体を使用し、構造体に値を割り当てることができます。そして、生のバイトをコピーするunsafeコードを使用しています。それはスピードのために本当に必要でない限り、私はまだそれに対して助言します。そして、あなたはそれが苦痛だと思うかもしれません。)

private struct MyStruct
{
    public short A;
    public short B;

    public MyStruct(short a, short b)
    {
        A = a;
        B = b;
    }
}

private unsafe byte[] UnsafeStruct(MyStruct myStruct)
{
    byte[] buffer = new byte[4]; // where 4 is the size of the struct
    fixed (byte* ptr = buffer)
    {
        *((MyStruct*)ptr) = myStruct;
    }
    return buffer;
}

少しだけシフト...

buffer[0]=(byte)SomeShort;
buffer[1]=(byte)(SomeShort >> 8);
buffer[2]=(byte)SomeOtherShort;
buffer[3]=(byte)(SomeOtherShort >> 8);

これはまた、あなたがエンディアンを完全に制御していること(この場合は、リトルエンディアン)

Array.Copy を使用するとコードを少し短くすることができますが、BitConverter にはバイトをバッファに直接入れる GetBytes オーバーロードや同等の機能はありません。

多分 バイナリライターメモリストリーム あなたが欲しいものは何ですか?

気に入らない BitConverter の API 規約を採用すると、クラスのユーザーに同じ問題が発生することに注意してください。代わりに、BinaryWriter を受け入れ、その中にクラスをシリアル化するメソッドを作成します。これは、クラスが他のオブジェクトに埋め込まれている場合にうまく拡張できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top