Преобразование необработанных байтовых значений в типы Java - PullRequest
2 голосов
/ 17 января 2011

У меня проблема с преобразованием необработанных байтовых значений в типы Java.Я получаю байты через сокет дейтаграммы как массив байтов.Я точно знаю, какие байты означают что, но я не знаю, как их соответствующим образом преобразовать (я имею в виду, что знаю смещения, но не знаю, правильно ли то, что я думаю, что получил;)).Например, я хочу преобразовать 16-битный беззнаковый шорт в тип Java Int.Я нашел несколько примеров в Интернете, один из которых:

public int getUShort(byte[] bytes, int offset) {
    int b0 = bytes[offset] & oxFF;
    int b1 = bytes[offset + 1] & oxFF;

    return (b1 << 8) + (b0 << 0);

Другой - тот же, но последняя строка:

return (b0 << 8)  + b1;

Конечно, это дает разные результаты.Который правильный?Можете ли вы дать мне также действительный пример, как сделать то же самое, но без подписи?

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 17 января 2011

Некоторое время назад мне пришлось выполнить некоторую работу, аналогичную этой, и я обнаружил, что лучший способ выполнить такую ​​работу - это использовать ByteBuffer и его преобразования в DoubleBuffer, LongBuffer и т. Д. Вы можетепреобразовать массив байтов в ByteBuffer, вызвав

ByteBuffer myBuffer = ByteBuffer.wrap(myRawArray);

Оттуда вы можете получить представление байтов в виде списка int s, вызвав

IntBuffer myIntBuffer = myBuffer.asIntBuffer();

и вы можете затем преобразовать байты, вызвав

int nextInt = myIntBuffer.get();

Эти классы также имеют большую поддержку для массовых операций get, так что если вы точно знаете, что получаете целую кучу данныхпо сети того же типа вы можете выполнять преобразования очень быстро.

Альтернативным подходом было бы, если это вообще возможно, использовать какую-либо сериализацию на основе Java для отправки данных по сети.Это позволяет вам делать преобразования намного проще, используя классы потоковой записи.Конечно, это может быть недоступно, особенно если вы общаетесь с сервером, отличным от Java, но его стоит изучить.

1 голос
/ 17 апреля 2012

Очень поздно на этом.

Оба являются правильными в зависимости от порядка данных.Смотрите здесь: http://en.wikipedia.org/wiki/Endianness

return (b1 << 8) + b0;//little endian
return (b0 << 8) + b1;//big endian
1 голос
/ 17 января 2011

Вы можете использовать DataInputStream или ByteBuffer для чтения различных типов. Вы можете использовать подписанные типы как значения без знака для большинства операций точно так же. Я написал простой класс, чтобы проиллюстрировать, как вы можете использовать подписанные типы, как если бы они были без знака Без знака

ByteBuffer b = ByteBuffer.wrap(bytes);
short s = b.getShort();
long l = b.getLong();
...