Получает байтовый массив из ByteBuffer в java

Ответы:

108

Зависит от того, что вы хотите делать.

Если вы хотите получить оставшиеся байты (между положением и пределом), то то, что у вас есть, будет работать. Вы также можете просто сделать:

ByteBuffer bb =..

byte[] b = new byte[bb.remaining()];
bb.get(b);

что эквивалентно javadocs ByteBuffer.

Джейсон С
источник
6
Верный. И обратите внимание, что это bb.capacity() может быть равным, bb.remaining()даже если резервный массив длиннее, поэтому вы не должны использовать их равенство в качестве проверки bb.array()правильности. Смотрите ByteBuffer.slice().
cdunn2001
1
Обратите внимание, что, чтобы не менять положение буфера, я использовал bb.slice().remaining(). Таким образом, он выглядит как чистый дамп, не затрагивая исходный буфер.
Kyll
этот метод дает мне подписанные байты, но я хочу беззнаковые ... любая идея?
H Raval
В Java нет понятия целых чисел без знака, есть только числа со знаком. Если вам нужны «байты без знака», вам нужно преобразовать как intи использовать битовую маску: int unsigned_byte = b[k] & 0xff;для некоторого значения k.
Джейсон С.
Если вы хотите получить весь буфер в байтовый массив, вы бы ByteBuffer#clearсначала позвонили ?
Kenny Worden
21

Обратите внимание, что bb.array () не учитывает положение байтовых буферов и может быть еще хуже, если байтовый буфер, с которым вы работаете, является частью другого буфера.

Т.е.

byte[] test = "Hello World".getBytes("Latin1");
ByteBuffer b1 = ByteBuffer.wrap(test);
byte[] hello = new byte[6];
b1.get(hello); // "Hello "
ByteBuffer b2 = b1.slice(); // position = 0, string = "World"
byte[] tooLong = b2.array(); // Will NOT be "World", but will be "Hello World".
byte[] world = new byte[5];
b2.get(world); // world = "World"

Что может быть не тем, что вы собираетесь делать.

Если вы действительно не хотите копировать байтовый массив, обходным решением может быть использование arrayOffset () + Остающийся () байтового буфера, но это работает только в том случае, если приложение поддерживает индекс + длину байтовых буферов. потребности.

R4zorax
источник
«bb.array () не учитывает положение байтовых буферов», не могли бы вы предоставить нам более подробную информацию об этой части. Я понял пример среза, но мне нужно больше подробностей о том, почему bb.array ()
испортилась
5

Так просто, как, что

  private static byte[] getByteArrayFromByteBuffer(ByteBuffer byteBuffer) {
    byte[] bytesArray = new byte[byteBuffer.remaining()];
    byteBuffer.get(bytesArray, 0, bytesArray.length);
    return bytesArray;
}
Салман Назир
источник
4
final ByteBuffer buffer;
if (buffer.hasArray()) {
    final byte[] array = buffer.array();
    final int arrayOffset = buffer.arrayOffset();
    return Arrays.copyOfRange(array, arrayOffset + buffer.position(),
                              arrayOffset + buffer.limit());
}
// do something else
Джин Квон
источник
4

Если кто-то ничего не знает о внутреннем состоянии данного (Direct) ByteBuffer и хочет получить все содержимое буфера, это можно использовать:

ByteBuffer byteBuffer = ...;
byte[] data = new byte[byteBuffer.capacity()];
((ByteBuffer) byteBuffer.duplicate().clear()).get(data);
Томаш Мышик
источник
ByteBuffer.get(byte[])возвращает aByteBuffer
pyb
А также...? Не понимаю, что вы имеете в виду, извините.
Tomáš Myšík 01
Вопрос в том, как перейти от ByteBuffer к byte [].
pyb 01
2
После вызова они находятся в dataпеременной. Получатель возвращается this, см. Его Javadoc.
Tomáš Myšík 01
Спасибо, я этого не понял. Поскольку метод get возвращает значение, я не ожидал, что у него также будет побочный эффект.
pyb 01
1

Это простой способ получить byte [], но часть смысла использования ByteBuffer состоит в том, чтобы избежать необходимости создавать byte []. Возможно, вы сможете получить все, что хотите, из байта [] прямо из ByteBuffer.

Питер Лоури
источник
15
Но часто вам нужно вызвать что-то (не в вашем собственном коде), которое принимает byte [], поэтому преобразование не является необязательным.
Джеймс Мур