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.