Pobiera tablicę bajtów z ByteBuffer w java


96

Czy jest to zalecany sposób pobierania bajtów z ByteBuffer

ByteBuffer bb =..

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

Odpowiedzi:


108

Zależy od tego, co chcesz zrobić.

Jeśli chcesz pobrać pozostałe bajty (między pozycją a limitem), wtedy to, co masz, zadziała. Możesz też po prostu zrobić:

ByteBuffer bb =..

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

co jest równoważne z javadocs ByteBuffer .


6
Poprawny. Zauważ, że bb.capacity() może się to równać bb.remaining()nawet wtedy, gdy tablica podstawowa jest dłuższa, więc nie możesz używać ich równości jako testu, kiedy bb.array()jest poprawna. Zobacz ByteBuffer.slice().
cdunn2001

1
Zwróć uwagę, że aby uniknąć zmiany położenia bufora, użyłem bb.slice().remaining(). W ten sposób wygląda jak czysty zrzut bez dotykania oryginalnego bufora.
Kyll

ta metoda daje mi podpisane bajty, ale chcę bez znaku ... jakiś pomysł?
H Raval

Java nie ma pojęcia liczb całkowitych bez znaku, tylko ze znakiem. Jeśli chcesz mieć „bajty bez znaku”, musisz rzutować jako inti użyć maski bitowej: int unsigned_byte = b[k] & 0xff;dla jakiejś wartości k.
Jason S

Jeśli chcesz pobrać cały bufor do tablicy bajtów, czy zadzwonisz ByteBuffer#clearnajpierw?
Kenny Worden

21

Zauważ, że bb.array () nie honoruje pozycji buforów bajtów i może być nawet gorsze, jeśli bufor bajtowy, nad którym pracujesz, jest fragmentem innego bufora.

To znaczy

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"

Co może nie być tym, co zamierzasz zrobić.

Jeśli naprawdę nie chcesz kopiować tablicy bajtów, rozwiązaniem może być użycie tablicy bufora bajtów () + pozostały (), ale działa to tylko wtedy, gdy aplikacja obsługuje indeks + długość buforów bajtów. wymagania.


„bb.array () nie honoruje pozycji buforów bajtów”, czy możesz podać nam więcej szczegółów na temat tej części. Zrozumiałem przykład plastra, ale potrzebuję więcej szczegółów na temat tego, dlaczego bb.array ()
zepsuło

5

Tak proste jak to

  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

Jeśli nie wiemy nic o stanie wewnętrznym danego (bezpośredniego) ByteBuffera i chce się pobrać całą zawartość bufora, można to wykorzystać:

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

ByteBuffer.get(byte[])zwraca aByteBuffer
pyb

I...? Nie wiem, co masz na myśli, przepraszam.
Tomáš Myšík

Pytanie brzmi, jak przejść z ByteBuffer do bajtu [].
pyb

2
Raz wywołane są w datazmiennej. Getter powraca this, zobacz jego Javadoc.
Tomáš Myšík

Dzięki, nie rozumiem. Ponieważ metoda get zwraca wartość, nie spodziewałem się, że będzie miała również efekt uboczny.
pyb

1

Jest to prosty sposób na uzyskanie bajtu [], ale częścią zastosowania ByteBuffer jest uniknięcie konieczności tworzenia bajtu []. Być może możesz uzyskać wszystko, co chcesz, z bajtu [] bezpośrednio z ByteBuffer.


15
Ale często będziesz musiał wywołać coś (nie we własnym kodzie), co zajmuje bajt [], więc konwersja nie jest opcjonalna.
James Moore,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.