Java'da ByteBuffer'dan bayt dizisini alır


99

ByteBuffer'dan bayt almanın önerilen yolu bu mu?

ByteBuffer bb =..

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

Yanıtlar:


109

Ne yapmak istediğine bağlı.

İstediğiniz kalan baytları almaksa (konum ve sınır arasında), o zaman sahip olduğunuz şey çalışacaktır. Ayrıca şunları da yapabilirsiniz:

ByteBuffer bb =..

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

burada uygun olarak eşdeğerdir ByteBuffer javadocs.


6
Doğru. Ve destek dizisi daha uzun olduğunda bile bunun eşit bb.capacity() olabileceğini unutmayın bb.remaining(), bu nedenle eşitliklerini ne zaman bb.array()doğru olduğuna dair bir test olarak kullanmamalısınız . Bakın ByteBuffer.slice().
cdunn2001

1
Tamponun konumunu değiştirmemek için kullandım bb.slice().remaining(). Bu şekilde, orijinal tampona dokunmadan temiz bir çöplük gibi görünür.
Kyll

bu yöntem bana imzalı bayt veriyor ancak işaretsiz istiyorum ... herhangi bir fikir?
H Raval

Java'da işaretsiz tamsayılar yoktur, sadece işaretli olanlar vardır. Eğer "işaretsiz baytlar" istiyorsanız, intbir bit maskesi kullanmalısınız: int unsigned_byte = b[k] & 0xff;değerinin bir değeri için k.
Jason S

Tamponun tamamını bir bayt dizisine almak istiyorsanız, ByteBuffer#clearönce çağırır mısınız?
Kenny Worden

21

Bb.array () işlevinin bayt arabellek konumunu kabul etmediğini ve üzerinde çalıştığınız baytebuffer başka bir arabellek dilimi ise daha da kötü olabileceğini unutmayın.

Yani

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"

Yapmak istediğin şey bu olmayabilir.

Bayt dizisini gerçekten kopyalamak istemiyorsanız, geçici bir çözüm, bayt arabelleğinin arrayOffset () + kalan () işlevini kullanmak olabilir, ancak bu yalnızca uygulama, bayt arabelleğinin dizin + uzunluğunu destekliyorsa işe yarar. ihtiyacı var.


"bb.array (), bayt arabellek konumunu kabul etmez", bize bu bölüm hakkında daha fazla ayrıntı verebilir misiniz? Dilim örneğini anladım, ancak bb.array () neden hata yaptığına dair daha fazla ayrıntıya ihtiyacım var
kkrishnaai

5

Kadar basit

  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

Verilen (Doğrudan) ByteBuffer'ın dahili durumu hakkında hiçbir şey bilmiyorsanız ve tamponun tüm içeriğini almak istiyorsa, bu kullanılabilir:

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

ByteBuffer.get(byte[])döndürür aByteBuffer
pyb

Ve...? Ne demek istediğinden emin değilim, üzgünüm.
Tomáš Myšík

Soru, bir ByteBuffer'dan bir bayta [] nasıl geçileceğidir.
pyb

2
Çağrıldıktan sonra datadeğişkenin içindedirler. Alıcı geri döner this, Javadoc'una bakın.
Tomáš Myšík

Teşekkürler, anlamadım. Get yöntemi bir değer döndürdüğünden, onun da bir yan etkisi olmasını beklemiyordum.
pyb

1

Bu, bir bayt [] almanın basit bir yoludur, ancak ByteBuffer kullanmanın amacının bir kısmı, bir bayt [] oluşturmak zorunda kalmamaktır. Belki de almak istediğiniz her şeyi bayttan [] doğrudan ByteBuffer'dan alabilirsiniz.


15
Ancak genellikle bir bayt [] alan bir şeyi (kendi kodunuzda olmayan) çağırmanız gerekir, bu nedenle dönüştürme isteğe bağlı değildir.
James Moore
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.