4

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

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

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

4

5 回答 5

6

BinaryWriter 非常高效:

    byte[] ToBytes() {
        var ms = new MemoryStream(somelength);
        var bw = new BinaryWriter(ms);
        bw.Write(SomeShort);
        bw.Write(SomeOtherShort);
        return ms.ToArray();
    }
于 2010-03-26T22:28:49.620 回答
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();
于 2010-03-26T22:02:13.830 回答
1

只是位移...

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

这也意味着您可以完全控制字节序(在本例中为小字节序)

于 2010-03-26T23:57:36.940 回答
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;
}
于 2010-03-26T23:03:03.107 回答
0

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

也许MemoryStream上的BinaryWriter是您想要的?

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

于 2010-03-26T22:00:01.013 回答