ByteBuffer getInt () вопрос
мы используем Java ByteBuffer для связи сокетов с сервером C++. Мы знаем, что Java является Big-endian и сокет связи также Big-endian. Поэтому всякий раз, когда поток байтов получен и помещен в ByteBuffer Java, мы вызываем getInt (), чтобы получить значение. Никаких проблем, никакого обращения.
но если каким-то образом мы специально установили порядок байтов ByteBuffer в Little-endian (мой коллега действительно сделал это),
Java автоматически преобразует Тупоконечниками в младший разряд, когда данные в ByteBuffer?
тогда getInt () версии Little-endian вернет вам правильное значение?
Я думаю, что ответ на два вышеуказанных вопроса-да. Но когда я пытаюсь проверить свои догадки и попытаться найти, как работает getInt() в ByteBuffer, я обнаружил, что это абстрактный метод. Единственным подклассом ByteBuffer является класс MappedByteBuffer, который не реализовал абстрактное getInt (). Итак, где же реализация метода getInt ()?
для отправки, потому что мы используем Little-endian ByteBuffer, нам нужно преобразовать их в байты Big-endian, прежде чем мы поместим в сокет.
2 ответов
Итак, где же реализация метода 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) собственному порядку байтов; (b) является большим эндианом.
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 ByteBuffers будут переупорядочивать байты, как вы указываете.