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

Это рекомендуемый способ получить байты из ByteBuffer?

ByteBuffer bb =..

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

person kal    schedule 24.03.2009    source источник


Ответы (5)


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

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

ByteBuffer bb =..

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

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

person Jason S    schedule 24.03.2009
comment
Правильный. И обратите внимание, что bb.capacity() может равняться bb.remaining(), даже если резервный массив длиннее, поэтому вы не должны использовать их равенство в качестве проверки правильности bb.array(). См. ByteBuffer.slice(). - person cdunn2001; 26.09.2012
comment
Обратите внимание, чтобы избежать изменения положения буфера, я использовал bb.slice().remaining(). Таким образом, он выглядит как чистый дамп, не касаясь исходного буфера. - person Kyll; 21.01.2017
comment
этот метод дает мне подписанные байты, однако я хочу неподписанные... есть идеи? - person H Raval; 14.04.2017
comment
В Java нет понятия целых чисел без знака, только числа со знаком. Если вам нужны байты без знака, вам нужно преобразовать их как int и использовать битовую маску: int unsigned_byte = b[k] & 0xff; для некоторого значения k. - person Jason S; 15.04.2017
comment
Если вы хотите получить весь буфер в массив байтов, вы бы сначала вызвали ByteBuffer#clear? - person Kenny Worden; 09.06.2018

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

I.e.

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 () + оставшийся (), но это работает только в том случае, если приложение поддерживает индекс + длину байтовых буферов. потребности.

person R4zorax    schedule 19.11.2012
comment
bb.array() не учитывает положение байтовых буферов, можете ли вы предоставить нам более подробную информацию об этой части. Я понял пример среза, но мне нужно больше подробностей о том, почему bb.array() испортил - person kkrishnaai; 22.05.2019

Так просто

  private static byte[] getByteArrayFromByteBuffer(ByteBuffer byteBuffer) {
    byte[] bytesArray = new byte[byteBuffer.remaining()];
    byteBuffer.get(bytesArray, 0, bytesArray.length);
    return bytesArray;
}
person Salman Nazir    schedule 10.10.2017

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

ByteBuffer byteBuffer = ...;
byte[] data = new byte[byteBuffer.capacity()];
((ByteBuffer) byteBuffer.duplicate().clear()).get(data);
person Tomáš Myšík    schedule 04.02.2017
comment
ByteBuffer.get(byte[]) возвращает ByteBuffer - person pyb; 20.07.2018
comment
И...? Не уверен, что вы имеете в виду, извините. - person Tomáš Myšík; 01.08.2018
comment
Вопрос в том, как перейти от ByteBuffer к byte[]. - person pyb; 01.08.2018
comment
После вызова они находятся в переменной data. Геттер возвращает this, см. его Javadoc. - person Tomáš Myšík; 01.08.2018
comment
Спасибо, я этого не понял. Поскольку метод get возвращает значение, я не ожидал, что он также будет иметь побочный эффект. - person pyb; 01.08.2018

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

person Peter Lawrey    schedule 24.03.2009
comment
Но часто вам нужно вызвать что-то (не в вашем собственном коде), которое принимает byte[], поэтому преобразование не является обязательным. - person James Moore; 16.03.2011