Ottiene un array di byte da un ByteBuffer in java


95

È questo il modo consigliato per ottenere i byte da ByteBuffer

ByteBuffer bb =..

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

Risposte:


107

Dipende da cosa vuoi fare.

Se quello che vuoi è recuperare i byte rimanenti (tra posizione e limite), allora quello che hai funzionerà. Potresti anche fare semplicemente:

ByteBuffer bb =..

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

che è equivalente ai javadoc ByteBuffer .


6
Corretta. E nota che bb.capacity() potrebbe essere uguale bb.remaining()anche quando l'array di supporto è più lungo, quindi non devi usare la loro uguaglianza come test di quando bb.array()è corretto. Vedi ByteBuffer.slice().
— cdunn2001

1
Notare che, per evitare di cambiare la posizione del buffer, ho usato bb.slice().remaining(). In questo modo sembra un dump pulito senza toccare il buffer originale.
— Kyll

questo metodo mi dà byte firmati ma voglio non firmati ... qualche idea?
— H Raval

Java non ha la nozione di interi senza segno, solo quelli con segno. Se vuoi "byte senza segno", devi eseguire il cast as inte utilizzare una maschera di bit: int unsigned_byte = b[k] & 0xff;per un valore di k.
— Jason S

Se vuoi inserire l'intero buffer in un array di byte, chiameresti ByteBuffer#clearprima?
— Kenny Worden

21

Nota che bb.array () non rispetta la posizione byte-buffer, e potrebbe essere anche peggio se il bytebuffer su cui stai lavorando è una fetta di qualche altro buffer.

Cioè

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"

Che potrebbe non essere quello che intendi fare.

Se davvero non vuoi copiare l'array di byte, una soluzione potrebbe essere quella di utilizzare arrayOffset () + residuo () del byte-buffer, ma funziona solo se l'applicazione supporta indice + lunghezza del byte-buffer esigenze.


"bb.array () non rispetta la posizione dei byte-buffer", puoi fornirci maggiori dettagli su questa parte. Ho capito l'esempio di slice ma ho bisogno di maggiori dettagli sul motivo per cui bb.array () incasina
— kkrishnaai

5

Così semplice

  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 non si sa nulla dello stato interno del ByteBuffer (diretto) dato e si desidera recuperare l'intero contenuto del buffer, è possibile utilizzare questo:

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

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

E...? Non sono sicuro di cosa intendi, scusa.
— Tomáš Myšík

La domanda è come passare da un ByteBuffer a un byte [].
— pyb

2
Una volta chiamati, sono nella datavariabile. Il getter ritorna this, guarda il suo Javadoc.
— Tomáš Myšík

Grazie, non ho capito. Poiché il metodo get restituisce un valore, non mi aspettavo che avesse anche un effetto collaterale.
— pyb

1

Questo è un modo semplice per ottenere un byte [], ma parte del punto dell'utilizzo di un ByteBuffer è evitare di dover creare un byte []. Forse puoi ottenere quello che vuoi ottenere dal byte [] direttamente dal ByteBuffer.


15
Ma spesso dovrai chiamare qualcosa (non nel tuo codice) che richiede un byte [], quindi la conversione non è facoltativa.
— James Moore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.