JavaのByteBufferからバイト配列を取得します


94

これは、ByteBufferからバイトを取得するための推奨される方法ですか?

ByteBuffer bb =..

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

回答:


107

あなたが何をしたいかに依存します。

残りのバイト(位置と制限の間)を取得する必要がある場合は、使用しているものが機能します。次のようにすることもできます:

ByteBuffer bb =..

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

これは、ByteBuffer javadocs と同等です。


6
正しい。また、バッキング配列が長い場合でも等しい場合があるので、いつ等しいbb.capacity() かをbb.remaining()テストするためにそれらの等価性を使用しないでくださいbb.array()。を参照してくださいByteBuffer.slice()
cdunn2001 2001

1
バッファの位置を変更しないようにするために、私はを使用したことに注意してくださいbb.slice().remaining()。こうすることで、元のバッファに触れずにクリーンダンプのように見えます。
Kyll

この方法では、署名されたバイトが得られますが、署名なしが必要です...
Hラバル2017

Javaには符号なし整数の概念はありません。符号付き整数のみです。あなたは「符号なしバイトを」したい場合は、としてキャストに必要intとビットマスクを使用します。int unsigned_byte = b[k] & 0xff;いくつかの値についてk
ジェイソンS

バッファ全体をバイト配列にしたい場合は、ByteBuffer#clear最初に呼び出しますか?
ケニーワーデン

21

bb.array()はバイトバッファーの位置を考慮しないため、作業中のバイトバッファーが他のバッファーのスライスである場合はさらに悪いことに注意してください。

すなわち

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"

それはあなたがやろうとしていることではないかもしれません。

バイト配列をコピーしたくない場合は、バイトバッファーのarrayOffset()+残り()を使用することで回避できますが、これは、アプリケーションがバイトバッファーのインデックス+長さをサポートしている場合にのみ機能します。ニーズ。


「bb.array()はバイトバッファの位置を考慮しません」、この部分の詳細を教えてください。私はスライスの例を理解しましたが、なぜbb.array()が失敗するかについての詳細が必要です
kkrishnaai

5

それと同じくらい簡単

  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

指定された(Direct)ByteBufferの内部状態について何も知らず、バッファのコンテンツ全体を取得したい場合、これを使用できます。

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

ByteBuffer.get(byte[])リターンByteBuffer
PYB

そして...?意味がわからない、ごめんなさい。
トマーシュMyšík

問題は、ByteBufferからbyte []に​​移動する方法です。
pyb 2018

2
呼び出されると、data変数に含まれます。ゲッターはを返しますthis。Javadocを参照してください。
トマーシュMyšík

ありがとう、うまく聞き取れませんでした。getメソッドは値を返すため、副作用も期待していませんでした。
pyb 2018

1

これはbyte []を取得する簡単な方法ですが、ByteBufferを使用するポイントの一部は、byte []を作成する必要がないことです。おそらく、ByteBufferから直接byte []から取得したいものを何でも取得できます。


15
しかし、多くの場合、(独自のコードではなく)byte []をとる何かを呼び出す必要があるため、変換はオプションではありません。
James Moore、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.