Mendapat array byte dari ByteBuffer di java

96

Apakah ini cara yang disarankan untuk mendapatkan byte dari ByteBuffer

ByteBuffer bb =..

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

Jawaban:

108

Tergantung apa yang ingin Anda lakukan.

Jika yang Anda inginkan adalah mengambil byte yang tersisa (antara posisi dan batas), maka apa yang Anda miliki akan berfungsi. Anda juga bisa melakukan:

ByteBuffer bb =..

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

yang setara dengan javadocs ByteBuffer .

Jason S
sumber
6
Benar. Dan perhatikan bahwa bb.capacity() mungkin sama bb.remaining()bahkan ketika array pendukung lebih panjang, jadi Anda tidak boleh menggunakan persamaannya sebagai pengujian kapan bb.array()benar. Lihat ByteBuffer.slice().
cdunn2001
1
Perhatikan bahwa, untuk menghindari mengubah posisi buffer, saya menggunakan bb.slice().remaining(). Dengan cara itu terlihat seperti tempat pembuangan bersih tanpa menyentuh penyangga asli.
Kyll
metode ini memberi saya byte yang ditandatangani tetapi saya ingin unsigned ... ada ide?
H Raval
Java tidak memiliki pengertian tentang unsigned integer, hanya yang bertanda tangan. Jika Anda menginginkan "unsigned bytes", Anda perlu mentransmisikan intdan menggunakan bitmask: int unsigned_byte = b[k] & 0xff;untuk beberapa nilai k.
Jason S
Jika Anda ingin memasukkan seluruh buffer ke dalam array byte, apakah Anda akan menelepon ByteBuffer#cleardulu?
Kenny Worden
21

Perhatikan bahwa bb.array () tidak menghormati posisi buffer-byte, dan mungkin lebih buruk lagi jika bytebuffer yang Anda kerjakan adalah potongan dari beberapa buffer lain.

Yaitu

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"

Yang mungkin bukan yang ingin Anda lakukan.

Jika Anda benar-benar tidak ingin menyalin byte-array, penyelesaiannya bisa dengan menggunakan arrayOffset () + sisa () buffer-buffer, tetapi ini hanya berfungsi jika aplikasi mendukung indeks + panjang byte-buffer itu. kebutuhan.

R4zorax
sumber
"bb.array () tidak menghormati posisi byte-buffer", dapatkah Anda memberi kami detail lebih lanjut tentang bagian ini. Saya mengerti contoh slice tetapi perlu detail lebih lanjut tentang mengapa bb.array () mengacaukan
kkrishnaai
5

Sesimpel itu

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

Jika seseorang tidak tahu apa-apa tentang keadaan internal dari ByteBuffer (Langsung) yang diberikan dan ingin mengambil seluruh konten buffer, ini dapat digunakan:

ByteBuffer byteBuffer = ...;
byte[] data = new byte[byteBuffer.capacity()];
((ByteBuffer) byteBuffer.duplicate().clear()).get(data);
Tomáš Myšík
sumber
ByteBuffer.get(byte[])mengembalikan aByteBuffer
pyb
Dan...? Tidak yakin apa yang Anda maksud, maaf.
Tomáš Myšík
Pertanyaannya adalah bagaimana beralih dari ByteBuffer ke byte [].
pyb
2
Setelah dipanggil, mereka berada di datavariabel. Pengambil kembali this, lihat Javadoc-nya.
Tomáš Myšík
Terima kasih, saya tidak mengerti. Karena metode get mengembalikan nilai, saya tidak mengharapkannya memiliki efek samping juga.
pyb
1

Ini adalah cara sederhana untuk mendapatkan byte [], tetapi bagian dari tujuan menggunakan ByteBuffer adalah menghindari keharusan membuat byte []. Mungkin Anda bisa mendapatkan apa pun yang Anda inginkan dari byte [] langsung dari ByteBuffer.

Peter Lawrey
sumber
15
Namun seringkali Anda harus memanggil sesuatu (bukan dalam kode Anda sendiri) yang membutuhkan byte [], jadi mengonversi bukanlah opsional.
James Moore