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

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

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创建一个新数组并为您返回。 关于GetBytesBuffer.BlockCopy ,但你可以使用像Buffer.BlockCopy这样的方法来简化复制操作。

如果你不是在一个性能关键的代码片段中做这个,你可以去LINQy做一些事情,比如:

 IEnumerable 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); 

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

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

也许在MemoryStream上的BinaryWriter是你想要的?

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

Interesting Posts