Existe uma maneira menos dolorosa de getbytes para um buffer que não está começando em 0?

StackOverflow https://stackoverflow.com/questions/2527018

  •  22-09-2019
  •  | 
  •  

Pergunta

Estou tendo que lidar com bytes crus em um projeto e preciso basicamente fazer algo assim

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

Sinto que isso está tão errado, mas não consigo encontrar nenhuma maneira melhor de fazê -lo. Existe uma maneira mais fácil?

Foi útil?

Solução

O BinaryWriter é muito eficiente:

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

Outras dicas

Você não precisa inicializar tmp para uma nova matriz. BitConverter.GetBytes Cria uma nova matriz e a devolve para você. Não há muito que você possa fazer sobre GetBytes Mas você pode usar métodos como Buffer.BlockCopy Para simplificar a operação de cópia.

Se você não está fazendo isso em uma peça de código crítica, você pode ficar um pouco linqy e fazer coisas 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();

Se você souber o tamanho de antemão (tenha um conjunto de tipos de valor), poderá usar uma estrutura e atribuir seus valores na estrutura. Em seguida, use unsafe código para copiar os bytes brutos. Eu ainda aconselharia contra, a menos que seja realmente necessário para fins de velocidade. E você pode pensar que é 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;
}

Apenas deslocamento ...

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

Isso também significa que você está no controle total do endian-ness (neste caso, Little-Endian)

Você pode tornar seu código um pouco mais curto usando o Array.copy, mas não, não há sobrecarga do GetBytes ou equivalente no BitConverter que coloca os bytes diretamente no seu buffer.

Pode ser BinaryWriter com um MemoryStream é o que você quer?

Observe que, ao adotar as convenções da API do BitConverter que você não gosta, você está causando o mesmo problema para os usuários da sua classe. Em vez disso, escreva um método que aceite um redator de binários e serialize sua classe nele, isso se estende muito bem quando sua classe é incorporada em algum outro objeto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top