对于不是从0开始的缓冲区,GetBytes是否有一种不太痛苦的方法?

时间:2010-03-26 21:56:55

标签: c# bytearray bitconverter

我不得不处理项目中的原始字节,我需要基本上做这样的事情

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];
}

我觉得这是错的,但我找不到更好的办法。有没有更简单的方法?

5 个答案:

答案 0 :(得分:6)

BinaryWriter非常有效:

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

答案 1 :(得分:3)

您无需将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();

答案 2 :(得分:1)

如果您事先知道大小(有一组值类型),您可以使用结构并在结构中分配您的值。然后使用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;
}

答案 3 :(得分:1)

只是换班......

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

这也意味着你可以完全控制字节序(在这种情况下,是小端)

答案 4 :(得分:0)

使用Array.Copy可以缩短代码,但BitConverter中没有任何GetBytes重载或等效项将字节直接放入缓冲区。

BinaryWriter上的MemoryStream可能是你想要的吗?

请注意,通过采用您不喜欢的BitConverter API约定,您会为您的类用户带来同样的问题。相反,编写一个接受BinaryWriter并将类序列化到其中的方法,当您的类嵌入到其他对象中时,这很好地扩展。