110 votes

Obtention d'un tableau d'octets à partir d'un ByteBuffer en java

Est-ce la façon recommandée de récupérer les octets du ByteBuffer ?

ByteBuffer bb =..

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

119voto

Jason S Points 58434

Ça dépend de ce que vous voulez faire.

Si ce que vous voulez, c'est récupérer les octets qui restent (entre la position et la limite), alors ce que vous avez fonctionnera. Vous pourriez aussi simplement faire :

ByteBuffer bb =..

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

qui est équivalent selon la ByteBuffer javadocs.

6 votes

Correct. Et notez que bb.capacity() pourrait égal bb.remaining() même si le tableau de sauvegarde est plus long. Vous ne devez donc pas utiliser leur égalité comme un test pour savoir quand bb.array() est correcte. Voir ByteBuffer.slice() .

1 votes

Notez que, pour éviter de changer la position du tampon, j'ai utilisé bb.slice().remaining() . De cette façon, cela ressemble à un vidage propre sans toucher au tampon d'origine.

0 votes

Cette méthode me donne des octets signés alors que je veux des octets non signés...une idée ?

24voto

Rasmus Fuglsang Points 80

Notez que bb.array() n'honore pas la position du tampon d'octets, et peut même être pire si le tampon d'octets sur lequel vous travaillez est une tranche d'un autre tampon.

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"

Ce qui n'est peut-être pas ce que vous avez l'intention de faire.

Si vous ne voulez vraiment pas copier le tableau d'octets, une solution de contournement pourrait être d'utiliser arrayOffset() + remaining() du tampon d'octets, mais cela ne fonctionne que si l'application supporte l'index + la longueur des tampons d'octets dont elle a besoin.

0 votes

"bb.array() ne respecte pas la position des byte-buffers", pouvez-vous nous fournir plus de détails sur cette partie. J'ai compris l'exemple du slice, mais j'ai besoin de plus de détails sur la raison pour laquelle bb.array() ne fonctionne pas.

8voto

Salman Nazir Points 1230

Aussi simple que cela

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

4voto

Tomáš Myšík Points 239

Si l'on ne sait rien de l'état interne du (Direct)ByteBuffer donné et que l'on souhaite récupérer l'intégralité du contenu du tampon, on peut utiliser cette fonction :

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

4voto

Jin Kwon Points 2191
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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X