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

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 .


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.


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

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

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

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.


15
Namun seringkali Anda harus memanggil sesuatu (bukan dalam kode Anda sendiri) yang membutuhkan byte [], jadi mengonversi bukanlah opsional.
James Moore
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.