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


95

Est-ce la méthode recommandée pour obtenir les octets du ByteBuffer

ByteBuffer bb =..

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

Réponses:


107

Ça dépend de ce que tu veux faire.

Si vous voulez récupérer les octets restants (entre la position et la limite), alors ce que vous avez fonctionnera. Vous pouvez aussi simplement faire:

ByteBuffer bb =..

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

qui est équivalent selon les javadocs ByteBuffer.


6
Correct. Et notez que cela bb.capacity() peut être égal bb.remaining()même lorsque le tableau de sauvegarde est plus long, vous ne devez donc pas utiliser leur égalité comme un test de quand bb.array()est correct. Voir ByteBuffer.slice().
cdunn2001

1
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 le tampon d'origine.
Kyll

cette méthode me donne des octets signés mais je veux non signés ... une idée?
H Raval

Java n'a pas la notion d'entiers non signés, seulement ceux signés. Si vous voulez des "octets non signés", vous devez effectuer un cast intet utiliser un masque de bits: int unsigned_byte = b[k] & 0xff;pour une valeur de k.
Jason S

Si vous voulez obtenir le tampon entier dans un tableau d'octets, appelez-vous en ByteBuffer#clearpremier?
Kenny Worden

21

Notez que bb.array () n'honore pas la position des byte-buffers, et pourrait être encore pire si le bytebuffer sur lequel vous travaillez est une tranche d'un autre tampon.

C'est à dire

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 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 le arrayOffset () + restant () du tampon d'octets, mais cela ne fonctionne que si l'application prend en charge l'index + la longueur des tampons d'octets. Besoins.


"bb.array () n'honore pas la position des byte-buffers", pouvez-vous nous fournir plus de détails sur cette partie. J'ai compris l'exemple de la tranche mais j'ai besoin de plus de détails sur les raisons pour lesquelles bb.array ()
gâche

5

Aussi simple que cela

  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

Si l'on ne sait rien de l'état interne du ByteBuffer (Direct) donné et veut récupérer tout le contenu du buffer, on peut l'utiliser:

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

ByteBuffer.get(byte[])renvoie aByteBuffer
pyb

Et...? Je ne sais pas ce que tu veux dire, désolé.
Tomáš Myšík

La question est de savoir comment passer d'un ByteBuffer à un byte [].
pyb

2
Une fois appelés, ils sont dans la datavariable. Le getter revient this, voir son Javadoc.
Tomáš Myšík

Merci, je n'ai pas compris. Étant donné que la méthode get renvoie une valeur, je ne m'attendais pas à ce qu'elle ait également un effet secondaire.
pyb

1

C'est un moyen simple d'obtenir un octet [], mais une partie du but d'utiliser un ByteBuffer est d'éviter d'avoir à créer un octet []. Peut-être pouvez-vous obtenir tout ce que vous vouliez obtenir de l'octet [] directement du ByteBuffer.


15
Mais souvent vous aurez besoin d'appeler quelque chose (pas dans votre propre code) qui prend un octet [], donc la conversion n'est pas facultative.
James Moore
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.