Obtém a matriz de bytes de um ByteBuffer em java


94

Esta é a maneira recomendada de obter os bytes do ByteBuffer

ByteBuffer bb =..

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

Respostas:


107

Depende do que você quer fazer.

Se o que você quer é recuperar os bytes restantes (entre a posição e o limite), então o que você tem vai funcionar. Você também pode simplesmente fazer:

ByteBuffer bb =..

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

que é equivalente de acordo com os javadocs ByteBuffer .


6
Corrigir. E observe que bb.capacity() pode ser igual bb.remaining()mesmo quando a matriz de apoio é mais longa, portanto, você não deve usar sua igualdade como um teste de quando bb.array()está correto. Veja ByteBuffer.slice().
— cdunn2001

1
Observe que, para evitar alterar a posição do buffer, usei bb.slice().remaining(). Dessa forma, parece um dump limpo sem tocar no buffer original.
— Kyll

este método me dá bytes assinados no entanto eu quero não assinados ... alguma idéia?
— H Raval

Java não tem a noção de inteiros sem sinal, apenas assinados. Se você quiser "bytes não assinados", você precisa lançar como inte usar uma máscara de bits: int unsigned_byte = b[k] & 0xff;para algum valor de k.
— Jason S,

Se você quiser colocar o buffer inteiro em uma matriz de bytes, você chamaria ByteBuffer#clearprimeiro?
— Kenny Worden

21

Observe que bb.array () não respeita a posição dos buffers de bytes e pode ser ainda pior se o bytebuffer em que você está trabalhando for uma fatia de algum outro buffer.

Ie

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"

O que pode não ser o que você pretende fazer.

Se você realmente não deseja copiar o byte-array, uma solução alternativa pode ser usar o arrayOffset () + restante () do buffer de bytes, mas isso só funciona se o aplicativo suportar índice + comprimento dos buffers de bytes necessidades.


"bb.array () não respeita a posição dos buffers de bytes", você pode nos fornecer mais detalhes sobre esta parte. Eu entendi o exemplo do slice, mas preciso de mais detalhes sobre por que bb.array () bagunça
— kkrishnaai

5

Tão simples como isso

  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

Se alguém não souber nada sobre o estado interno do ByteBuffer (direto) fornecido e quiser recuperar todo o conteúdo do buffer, isso pode ser usado:

ByteBuffer byteBuffer = ...;
byte[] data = new byte[byteBuffer.capacity()];
((ByteBuffer) byteBuffer.duplicate().clear()).get(data);

ByteBuffer.get(byte[])retorna aByteBuffer
— pyb

E...? Não tenho certeza do que você quer dizer, desculpe.
— Tomáš Myšík

A questão é como passar de um ByteBuffer para um byte [].
— pyb 01 de

2
Uma vez chamados, eles estão na datavariável. O getter retorna this, consulte seu Javadoc.
— Tomáš Myšík

Obrigado, não entendi. Como o método get está retornando um valor, eu não esperava que tivesse um efeito colateral também.
— pyb 01 de

1

Esta é uma maneira simples de obter um byte [], mas parte do objetivo de usar um ByteBuffer é evitar a criação de um byte []. Talvez você possa obter o que deseja obter do byte [] diretamente do ByteBuffer.


15
Mas frequentemente você precisará chamar algo (não em seu próprio código) que leva um byte [], então a conversão não é opcional.
— James Moore,
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.