Читать два байта в целое число? - PullRequest
24 голосов
/ 22 января 2011

У меня есть byte[], который я прочитал из файла, и я хочу получить int из двух байтов в нем.Вот пример:

byte[] bytes = new byte[] {(byte)0x00, (byte)0x2F, (byte)0x01, (byte)0x10, (byte)0x6F};
int value = bytes.getInt(2,4); //This method doesn't exist

Это должно сделать value равным 0x0110 или 272 в десятичном виде.Но, очевидно, byte[].getInt() не существует.Как я могу выполнить эту задачу?

Приведенный выше массив является лишь примером.Фактические значения мне неизвестны.

Ответы [ 6 ]

39 голосов
/ 22 января 2011

Вы должны просто выбрать простое:

int val = ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff);

Вы могли бы даже написать свою собственную вспомогательную функцию getBytesAsWord (byte[] bytes, int start), чтобы дать вам функциональность, если вы не хотите, чтобы вычисления пересекали ваш код, но я думаю,это, вероятно, было бы излишним.

6 голосов
/ 22 января 2011

Попробуйте:

public static int getInt(byte[] arr, int off) {
  return arr[off]<<8 &0xFF00 | arr[off+1]&0xFF;
} // end of getInt

В вашем вопросе не указано, что означают два аргумента (2,4).2 и 4 не имеют смысла в вашем примере, так как индексы в массиве для поиска ox01 и 0x10, я догадался, что вы хотите взять два последовательных элемента, это обычная вещь, поэтому я использовал off и off + 1 в моем методе.

Вы не можете расширить класс byte [] в java, поэтому у вас не может быть метода bytes.getInt, поэтому я создал статический метод, который использует byte [] в качестве первого аргумента.

Хитрость метода заключается в том, что ваши байты являются 8-битными знаковыми целыми числами, а значения свыше 0x80 являются отрицательными и будут расширяться знаком (т. Е. 0xFFFFFF80 при использовании в качестве целого числа).Вот почему маскирование '& 0xFF' необходимо.«<< 8» сдвигает более значимый оставшийся байт на 8 бит.'|'объединяет два значения - так же, как '+'.Порядок операторов важен, потому что << имеет наивысший приоритет, за которым следует & с последующим |- таким образом, скобки не нужны. </p>

3 голосов
/ 11 июля 2012

Вот хороший простой надежный способ.

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4);
    // by choosing big endian, high order bytes must be put
    // to the buffer before low order bytes
    byteBuffer.order(ByteOrder.BIG_ENDIAN);
    // since ints are 4 bytes (32 bit), you need to put all 4, so put 0
    // for the high order bytes
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x00);
    byteBuffer.put((byte)0x01);
    byteBuffer.put((byte)0x10);
    byteBuffer.flip();
    int result = byteBuffer.getInt();
1 голос
/ 22 января 2011

В качестве альтернативы вы можете использовать:

int val = (bytes[2] << 8) + bytes[3]
0 голосов
/ 24 октября 2013

Класс Google Base16 из Guava-14.0.1.

new BigInteger(com.google.common.io.BaseEncoding.base16().encode(bytesParam),16).longValue();
0 голосов
/ 22 января 2011

Вы можете использовать ByteBuffer. У него есть метод getInt, который вы ищете, и много других полезных методов

...