Pregunta

Estoy teniendo que lidiar con bytes sin formato en un proyecto y tengo que hacer algo como esto básicamente

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

Siento que este es tan mal pero no puedo encontrar nada mejor manera de hacerlo. hay una manera mas facil?

¿Fue útil?

Solución

BinaryWriter es muy eficiente:

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

Otros consejos

No es necesario inicializar tmp a una nueva matriz. BitConverter.GetBytes crea una nueva matriz y la devuelve para usted. No hay mucho que pueda hacer al respecto GetBytes pero se pueden utilizar métodos como Buffer.BlockCopy para simplificar la operación de copia.

Si usted no está haciendo esto en una pieza fundamental en el desempeño del código, se puede ir un poco LINQy y hacer cosas como:

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

Si se conoce el tamaño de antemano (tiene un conjunto de tipos de valor) se puede utilizar una estructura y asignar los valores de la estructura. A continuación, utilice el código unsafe para copiar los bytes sin formato. Me gustaría volver a desaconsejar a menos que sea realmente necesario para los propósitos de velocidad. Y se podría pensar que es doloroso:)

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

Sólo el bit de cambio ...

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

Esto también significa que está en completo control de la endian-dad (en este caso, ascendente hacia la izquierda)

Se puede hacer que el código un poco más corto mediante el uso de Array.Copy, pero no hay no hay ninguna sobrecarga GetBytes o su equivalente en BitConverter que pone los bytes directamente en su memoria intermedia.

BinaryWriter en un < a href = "http://msdn.microsoft.com/en-us/library/system.io.memorystream.aspx" rel = "nofollow noreferrer"> MemoryStream es lo que quiere?

Tenga en cuenta que mediante la adopción de las convenciones de la API de BitConverter que no les gusta, que está causando el mismo problema para los usuarios de su clase. En su lugar, escribir un método que acepta un BinaryWriter y serializa la clase en él, esto se extiende muy bien cuando tu clase está incrustado en algún otro objeto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top