Есть ли менее болезненный способ получить байты для буфера, не начинающегося с 0?

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

Если вы заранее знаете размер (имеете набор типов значений), вы могли бы использовать struct и присвоить свои значения в struct.Затем используйте 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.Скопируйте, но нет, в BitConverter нет перегрузки getBytes или эквивалента, который помещает байты непосредственно в ваш буфер.

Может быть Двоичный редактор на Поток памяти это то, чего ты хочешь?

Обратите внимание, что, принимая соглашения API BitConverter, которые вам не нравятся, вы создаете ту же проблему для пользователей вашего класса.Вместо этого напишите метод, который принимает BinaryWriter и сериализует в нем ваш класс, это прекрасно расширяется, когда ваш класс встроен в какой-либо другой объект.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top