ByteBuffer getInt () вопрос - PullRequest
       12

ByteBuffer getInt () вопрос

7 голосов
/ 04 августа 2011

Мы используем Java ByteBuffer для связи через сокет с сервером C ++.Мы знаем, что Java - Big-Endian, а Socket-связь также Big-Endian.Поэтому всякий раз, когда поток байтов получен и помещен в ByteBuffer Java, мы вызываем getInt () для получения значения.Без проблем, без преобразования.

Но если каким-то образом мы специально установим порядок байтов ByteBuffer в Little-endian (мой коллега на самом деле сделал это),

  1. будетJava автоматически конвертирует Big-endian в Little-endian, когда данные помещаются в ByteBuffer?

  2. Тогда getInt () версии Little-endian вернет вам правильное значение?

Я думаю, ответ на два вышевопросы да.Но когда я пытаюсь проверить свои догадки и попытаться выяснить, как getInt () работает в ByteBuffer, я обнаружил, что это абстрактный метод.Единственный подкласс ByteBuffer - это класс MappedByteBuffer, который не реализует абстрактный метод getInt ().Так где же реализация метода getInt ()?

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

Ответы [ 2 ]

9 голосов
/ 04 августа 2011

ByteBuffer автоматически использует указанный вами порядок байтов.(Или Big Endian по умолчанию)

 ByteBuffer bb =
 // to use big endian
 bb.order(ByteOrder.BIG_ENDIAN);

 // to use little endian
 bb.order(ByteOrder.LITTLE_ENDIAN);

 // use the natural order of the system.
 bb.order(ByteOrder.nativeOrder()); 

Как байты, так и байты direct и heap будут переупорядочивать байты по вашему усмотрению.

3 голосов
/ 04 августа 2011

Так где же реализация метода getInt ()?

ByteBuffer действительно абстрактный класс. Существует несколько способов создания байтовых буферов:

В моем JDK они создают экземпляры внутренних классов HeapByteBuffer и DirectByteBuffer. Соответствующие им функции getInt следующие:

// HeapByteBuffer

public int getInt() {
    return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
}

public int getInt(int i) {
    return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
}

и

// DirectByteBuffer

private int getInt(long a) {
    if (unaligned) {
        int x = unsafe.getInt(a);
        return (nativeByteOrder ? x : Bits.swap(x));
    }
    return Bits.getInt(a, bigEndian);
}

public int getInt() {
    return getInt(ix(nextGetIndex((1 << 2))));
}

public int getInt(int i) {
    return getInt(ix(checkIndex(i, (1 << 2))));
}

В приведенном выше примере nativeByteOrder и bigEndian - два логических элемента, указывающих соответственно - и несколько избыточно - соответствует ли сконфигурированный порядок байтов: (a) соответствует собственному порядку байтов; (б) является прямым порядком байтов.

...