Ruft ein Byte-Array aus einem ByteBuffer in Java ab

94

Ist dies die empfohlene Methode, um die Bytes aus dem ByteBuffer abzurufen?

ByteBuffer bb =..

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

Antworten:

107

Kommt darauf an, was du machen willst.

Wenn Sie die verbleibenden Bytes (zwischen Position und Limit) abrufen möchten, funktioniert das, was Sie haben. Sie könnten auch einfach tun:

ByteBuffer bb =..

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

Dies entspricht den ByteBuffer- Javadocs.

Jason S.
quelle
6
Richtig. Beachten Sie auch, dass dies bb.capacity() möglicherweise auch dann gleich ist bb.remaining(), wenn das Backing-Array länger ist. Sie dürfen daher die Gleichheit nicht als Test für die bb.array()Richtigkeit verwenden. Siehe ByteBuffer.slice().
cdunn2001
1
Beachten Sie, dass ich verwendet habe, um die Position des Puffers nicht zu ändern bb.slice().remaining(). Auf diese Weise sieht es aus wie ein sauberer Speicherauszug, ohne den ursprünglichen Puffer zu berühren.
Kyll
Diese Methode gibt mir signierte Bytes, aber ich möchte unsignierte ... irgendeine Idee?
H Raval
Java hat nicht die Vorstellung von vorzeichenlosen Ganzzahlen, sondern nur von vorzeichenbehafteten. Wenn Sie "vorzeichenlose Bytes" möchten, müssen Sie als intBitmaske umwandeln und verwenden: int unsigned_byte = b[k] & 0xff;für einen Wert von k.
Jason S
Wenn Sie den gesamten Puffer in ein Byte-Array umwandeln möchten, würden Sie ByteBuffer#clearzuerst aufrufen ?
Kenny Worden
21

Beachten Sie, dass bb.array () die Position der Bytepuffer nicht berücksichtigt und möglicherweise noch schlimmer ist, wenn der Bytebuffer, an dem Sie arbeiten, ein Teil eines anderen Puffers ist.

Dh

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"

Welches könnte nicht das sein, was Sie vorhaben.

Wenn Sie das Byte-Array wirklich nicht kopieren möchten, können Sie das ArrayOffset () + verbleibend () des Byte-Puffers verwenden. Dies funktioniert jedoch nur, wenn die Anwendung den Index + die Länge der Byte-Puffer unterstützt Bedürfnisse.

R4zorax
quelle
"bb.array () berücksichtigt die Position der Bytepuffer nicht", können Sie uns weitere Details zu diesem Teil mitteilen. Ich habe das Slice-Beispiel verstanden, brauche aber weitere Details darüber, warum bb.array () durcheinander
bringt
5

So einfach ist das

  private static byte[] getByteArrayFromByteBuffer(ByteBuffer byteBuffer) {
    byte[] bytesArray = new byte[byteBuffer.remaining()];
    byteBuffer.get(bytesArray, 0, bytesArray.length);
    return bytesArray;
}
Salman Nazir
quelle
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
Jin Kwon
quelle
4

Wenn man nichts über den internen Zustand des gegebenen (direkten) ByteBuffers weiß und den gesamten Inhalt des Puffers abrufen möchte, kann dies verwendet werden:

ByteBuffer byteBuffer = ...;
byte[] data = new byte[byteBuffer.capacity()];
((ByteBuffer) byteBuffer.duplicate().clear()).get(data);
Tomáš Myšík
quelle
ByteBuffer.get(byte[])gibt aByteBuffer
pyb
Und...? Ich bin mir nicht sicher, was du meinst, sorry.
Tomáš Myšík
Die Frage ist, wie man von einem ByteBuffer zu einem Byte [] wechselt.
Pyb
2
Einmal aufgerufen, befinden sie sich in der dataVariablen. Der Getter kehrt zurück this, siehe Javadoc.
Tomáš Myšík
Danke, das habe ich nicht verstanden. Da die get-Methode einen Wert zurückgibt, hatte ich nicht erwartet, dass er auch einen Nebeneffekt hat.
Pyb
1

Dies ist eine einfache Möglichkeit, ein Byte [] abzurufen. Ein Teil der Verwendung eines ByteBuffers besteht jedoch darin, zu vermeiden, dass ein Byte [] erstellt werden muss. Vielleicht können Sie aus dem Byte [] direkt aus dem ByteBuffer alles bekommen, was Sie wollen.

Peter Lawrey
quelle
15
Oft müssen Sie jedoch etwas aufrufen (nicht in Ihrem eigenen Code), das ein Byte [] benötigt, sodass die Konvertierung nicht optional ist.
James Moore