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);

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.


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.


"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;
}

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

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);

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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.