Java Language
ByteBuffer
Suche…
Einführung
Die ByteBuffer
Klasse wurde in Java 1.4 eingeführt, um das Arbeiten mit binären Daten zu erleichtern. Es ist besonders für die Verwendung mit primitiven Daten geeignet. Es erlaubt die Erzeugung, aber auch die nachfolgende Manipulation eines byte[]
auf einer höheren Abstraktionsebene
Syntax
- Byte [] Arr = neues Byte [1000];
- ByteBuffer buffer = ByteBuffer.wrap (arr);
- ByteBuffer Puffer = ByteBuffer.allocate (1024);
- ByteBuffer buffer = ByteBuffer.allocateDirect (1024);
- Byte b = Puffer.get ();
- Byte b = Puffer.get (10);
- kurz s = buffer.getShort (10);
- Puffer-Eingang ((Byte) 120);
- buffer.putChar ('a');
Grundlegende Verwendung - Erstellen eines ByteBuffers
Es gibt zwei Möglichkeiten, einen ByteBuffer
zu erstellen, bei dem einer erneut unterteilt werden kann.
Wenn Sie bereits ein byte[]
, können Sie es in einen ByteBuffer
"einhüllen" , um die Verarbeitung zu vereinfachen:
byte[] reqBuffer = new byte[BUFFER_SIZE];
int readBytes = socketInputStream.read(reqBuffer);
final ByteBuffer reqBufferWrapper = ByteBuffer.wrap(reqBuffer);
Dies wäre eine Möglichkeit für Code, der Netzwerkinteraktionen auf niedriger Ebene abwickelt
Wenn Sie noch kein byte[]
, können Sie einen ByteBuffer
über einem Array erstellen, das speziell für den Puffer wie ByteBuffer
reserviert ist:
final ByteBuffer respBuffer = ByteBuffer.allocate(RESPONSE_BUFFER_SIZE);
putResponseData(respBuffer);
socketOutputStream.write(respBuffer.array());
Wenn der Code-Pfad extrem leistungskritisch ist und Sie direkten Systemspeicherzugriff benötigen, kann der ByteBuffer
sogar direkte Puffer mit #allocateDirect()
Grundlegende Verwendung - Schreiben Sie Daten in den Puffer
Wenn eine ByteBuffer
Instanz gegeben ist, kann man Primitive-Typ-Daten mit relativen und absoluten put
ByteBuffer
sie schreiben. Der markante Unterschied besteht darin , dass die Daten unter Verwendung der relativen Methode verfolgt die Spuren des Index setzen die Daten an für Sie eingefügt wird, während die absolute Methode immer einen Index erfordert geben zu put
, die Daten an.
Beide Methoden erlauben das "Verketten" von Aufrufen. Bei einem ausreichend großen Puffer kann man dementsprechend Folgendes tun:
buffer.putInt(0xCAFEBABE).putChar('c').putFloat(0.25).putLong(0xDEADBEEFCAFEBABE);
was äquivalent ist zu:
buffer.putInt(0xCAFEBABE);
buffer.putChar('c');
buffer.putFloat(0.25);
buffer.putLong(0xDEADBEEFCAFEBABE);
Beachten Sie, dass die Methode, die für byte
wird, nicht speziell benannt wird. Außerdem beachten Sie, dass es auch gültig ist sowohl eine passieren ByteBuffer
und ein byte[]
zu put
. Ansonsten haben alle primitiven Typen spezielle put
Methoden.
Ein zusätzlicher Hinweis: Der bei Verwendung des absoluten put*
angegebene Index wird immer in byte
s gezählt.
Grundlegende Verwendung - Verwendung von DirectByteBuffer
DirectByteBuffer
ist eine spezielle Implementierung von ByteBuffer
, unter der kein byte[]
.
Wir können solche ByteBuffer durch Aufruf von:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(16);
Diese Operation belegt 16 Byte Speicher. Der Inhalt der direkten Puffer kann sich außerhalb des normalen Abfallsammelhaufens befinden.
Wir können überprüfen, ob ByteBuffer direkt ist, indem Sie Folgendes aufrufen:
directBuffer.isDirect(); // true
Die Hauptmerkmale von DirectByteBuffer
sind, dass JVM versucht, den zugewiesenen Speicher ohne zusätzliche Pufferung nativ zu bearbeiten, sodass die darauf durchgeführten Vorgänge möglicherweise schneller sind als die für ByteBuffers mit darunter liegenden Arrays.
Es wird empfohlen, DirectByteBuffer
mit DirectByteBuffer
Operationen zu verwenden, die von der Ausführungsgeschwindigkeit abhängig sind, wie z. B. Echtzeitkommunikation.
Wir müssen uns bewusst sein, dass wir, wenn wir die array()
-Methode versuchen, UnsupportedOperationException
. Daher ist es eine gute Praxis, zu prüfen, ob unser ByteBuffer (Byte-Array) vorhanden ist, bevor wir versuchen, darauf zuzugreifen:
byte[] arrayOfBytes;
if(buffer.hasArray()) {
arrayOfBytes = buffer.array();
}
Eine andere Verwendung des direkten Bytepuffers ist das Interop über die JNI. Da ein direkter Byte-Puffer kein byte[]
, sondern einen tatsächlichen Speicherblock verwendet, ist es möglich, über einen Zeiger im nativen Code direkt auf diesen Speicher zuzugreifen. Dies kann ein wenig Ärger und Mehraufwand beim Marshalling zwischen der Java- und der nativen Darstellung von Daten ersparen.
Die JNI-Schnittstelle definiert mehrere Funktionen, um direkte Bytepuffer zu behandeln: NIO-Unterstützung .