对于不从 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