Szukaj…


Wprowadzenie

Klasa ByteBuffer została wprowadzona w Javie 1.4, aby ułatwić pracę na danych binarnych. Jest szczególnie odpowiedni do użycia z danymi typu pierwotnego. Umożliwia tworzenie, ale także późniejsze manipulowanie byte[] na wyższym poziomie abstrakcji

Składnia

  • byte [] arr = nowy bajt [1000];
  • ByteBuffer buffer = ByteBuffer.wrap (arr);
  • ByteBuffer buffer = ByteBuffer.allocate (1024);
  • ByteBuffer buffer = ByteBuffer.allocateDirect (1024);
  • bajt b = buffer.get ();
  • bajt b = buffer.get (10);
  • short s = buffer.getShort (10);
  • buffer.put ((byte) 120);
  • buffer.putChar („a”);

Podstawowe użycie - tworzenie ByteBuffer

Istnieją dwa sposoby utworzenia ByteBuffer , w którym można ponownie podzielić.

Jeśli masz już byte[] , możesz go „owinąć” w ByteBuffer aby uprościć przetwarzanie:

byte[] reqBuffer = new byte[BUFFER_SIZE];
int readBytes = socketInputStream.read(reqBuffer);
final ByteBuffer reqBufferWrapper = ByteBuffer.wrap(reqBuffer);

To byłaby możliwość dla kodu, który obsługuje interakcje sieciowe niskiego poziomu


Jeśli nie masz jeszcze byte[] , możesz utworzyć ByteBuffer na tablicy specjalnie przypisanej do bufora, jak poniżej:

final ByteBuffer respBuffer = ByteBuffer.allocate(RESPONSE_BUFFER_SIZE);
putResponseData(respBuffer);
socketOutputStream.write(respBuffer.array());

Jeśli ścieżka kodu ma ogromne znaczenie dla wydajności i potrzebujesz bezpośredniego dostępu do pamięci systemowej , ByteBuffer może nawet przydzielić bezpośrednie bufory za pomocą #allocateDirect()

Podstawowe użycie - zapis danych do bufora

Biorąc pod uwagę ByteBuffer instancji można zapisywać dane prymitywne typu do niego przy użyciu względnej i bezwzględnej put . Uderzająca różnica polega na tym, że umieszczanie danych przy użyciu metody względnej śledzi indeks, w którym dane są wstawiane, podczas gdy metoda bezwzględna zawsze wymaga podania indeksu, w którym put są dane.

Obie metody umożliwiają połączenia „łańcuchowe” . Biorąc pod uwagę bufor o wystarczającej wielkości, można odpowiednio wykonać następujące czynności:

buffer.putInt(0xCAFEBABE).putChar('c').putFloat(0.25).putLong(0xDEADBEEFCAFEBABE);

co jest równoważne z:

buffer.putInt(0xCAFEBABE);
buffer.putChar('c');
buffer.putFloat(0.25);
buffer.putLong(0xDEADBEEFCAFEBABE);

Zauważ, że metoda działająca na byte nie jest specjalnie nazwana. Dodatkowo zauważ, że prawidłowe jest również przekazanie ByteBuffer i byte[] do put . Poza tym wszystkie pierwotne typy mają wyspecjalizowane metody put .

Dodatkowa uwaga: Indeks podany przy stosowaniu wartości bezwzględnej put* jest zawsze liczony w byte .

Podstawowe użycie - korzystanie z DirectByteBuffer

DirectByteBuffer to specjalna implementacja ByteBuffer którą nie ma byte[] .

Możemy przydzielić taki ByteBuffer, dzwoniąc:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(16);

Ta operacja przydzieli 16 bajtów pamięci. Zawartość bezpośrednich buforów może znajdować się poza zwykłą stertą śmieci.

Możemy sprawdzić, czy ByteBuffer jest bezpośredni, dzwoniąc:

directBuffer.isDirect(); // true

Główną cechą DirectByteBuffer jest to, że JVM spróbuje natywnie pracować na przydzielonej pamięci bez żadnego dodatkowego buforowania, więc operacje na nim wykonywane mogą być szybsze niż te wykonywane na ByteBuffers z tablicami leżącymi pod spodem.

Zaleca się stosowanie DirectByteBuffer przypadku ciężkich operacji IO, które polegają na szybkości wykonania, np. Komunikacji w czasie rzeczywistym.

Musimy mieć świadomość, że jeśli spróbujemy użyć metody array() , otrzymamy UnsupportedOperationException . Dobrą praktyką jest sprawdzanie, czy nasz ByteBuffer go ma (tablica bajtów), zanim spróbujemy uzyskać do niego dostęp:

 byte[] arrayOfBytes;
 if(buffer.hasArray()) {
     arrayOfBytes = buffer.array();
 }

Innym zastosowaniem bufora bezpośrednich bajtów jest interop przez JNI. Ponieważ bufor bezpośrednich bajtów nie korzysta z byte[] , lecz z rzeczywistego bloku pamięci, możliwe jest uzyskanie dostępu do tej pamięci bezpośrednio za pomocą wskaźnika w kodzie natywnym. Może to zaoszczędzić trochę kłopotów i narzutów podczas zestawiania między Javą a natywną reprezentacją danych.

Interfejs JNI definiuje kilka funkcji do obsługi bezpośrednich buforów bajtów: Obsługa NIO .



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow