Java Language
ByteBuffer
Sök…
Introduktion
ByteBuffer
klassen introducerades i java 1.4 för att underlätta arbetet med binära data. Det är särskilt lämpligt att använda med primitiva data. Det tillåter skapande, men också efterföljande manipulation av en byte[]
s på en högre abstraktionsnivå
Syntax
- byte [] arr = ny byte [1000];
- ByteBuffer-buffert = ByteBuffer.wrap (arr);
- ByteBuffer-buffert = ByteBuffer.allocate (1024);
- ByteBuffer-buffert = ByteBuffer.allocateDirect (1024);
- byte b = buffert.get ();
- byte b = buffert.get (10);
- kort s = buffert.getShort (10);
- buffert.utgång ((byte) 120);
- buffer.putChar ( 'a');
Grundläggande användning - Skapa en ByteBuffer
Det finns två sätt att skapa en ByteBuffer
, där man kan delas upp igen.
Om du har en redan befintlig byte[]
kan du "linda in den" i en ByteBuffer
att förenkla behandlingen:
byte[] reqBuffer = new byte[BUFFER_SIZE];
int readBytes = socketInputStream.read(reqBuffer);
final ByteBuffer reqBufferWrapper = ByteBuffer.wrap(reqBuffer);
Detta skulle vara en möjlighet för kod som hanterar nätverksinteraktioner på låg nivå
Om du inte har en redan befintlig byte[]
kan du skapa en ByteBuffer
över en matris som specifikt har allokerats för bufferten så här:
final ByteBuffer respBuffer = ByteBuffer.allocate(RESPONSE_BUFFER_SIZE);
putResponseData(respBuffer);
socketOutputStream.write(respBuffer.array());
Om kodvägen är extremt kritisk för prestanda och du behöver direkt åtkomst till ByteBuffer
kan ByteBuffer
med tilldela direkta buffertar med #allocateDirect()
Grundläggande användning - Skriv data till bufferten
Med en ByteBuffer
instans kan man skriva primitiva data till den med relativ och absolut put
. Den slående skillnaden är att om du lägger data med hjälp av den relativa metoden håller du reda på indexet som data infogas för dig, medan den absoluta metoden alltid kräver att ett index ska put
till.
Båda metoderna tillåter "kedja" samtal. Med en buffert med tillräckligt stor storlek kan man därför göra följande:
buffer.putInt(0xCAFEBABE).putChar('c').putFloat(0.25).putLong(0xDEADBEEFCAFEBABE);
vilket motsvarar:
buffer.putInt(0xCAFEBABE);
buffer.putChar('c');
buffer.putFloat(0.25);
buffer.putLong(0xDEADBEEFCAFEBABE);
Observera att metoden som fungerar på byte
inte heter särskilt. Observera dessutom att det också är giltigt att skicka både en ByteBuffer
och en byte[]
att put
. Annat än att har alla primitiva typer specialiserade put
-metoder.
En ytterligare anmärkning: Indexet som ges vid användning av absolut put*
räknas alltid i byte
s.
Grundläggande användning - Använda DirectByteBuffer
DirectByteBuffer
är en speciell implementering av ByteBuffer
som inte har någon byte[]
under.
Vi kan tilldela en sådan ByteBuffer genom att ringa:
ByteBuffer directBuffer = ByteBuffer.allocateDirect(16);
Denna operation kommer att tilldela 16 byte minne. Innehållet i direkta buffertar kan ligga utanför den vanliga skräppassaren.
Vi kan verifiera om ByteBuffer är direkt genom att ringa:
directBuffer.isDirect(); // true
De viktigaste egenskaperna hos DirectByteBuffer
är att JVM kommer att försöka arbeta med nativt på tilldelat minne utan ytterligare buffring så att operationer som utförs på den kan vara snabbare än de som utförs på ByteBuffers med matriser som ligger under.
Det rekommenderas att använda DirectByteBuffer
med tunga IO-operationer som förlitar sig på körhastighet, som kommunikation i realtid.
Vi måste vara medvetna om att om vi försöker använda array()
-metoden kommer vi att få UnsupportedOperationException
. Så det är en bra praxis att checka om vår ByteBuffer har det (byte-array) innan vi försöker komma åt det:
byte[] arrayOfBytes;
if(buffer.hasArray()) {
arrayOfBytes = buffer.array();
}
En annan användning av direktbyte-buffert är interop genom JNI. Eftersom en direktbyte-buffert inte använder en byte[]
, utan ett faktiskt minnesblock, är det möjligt att komma åt det minnet direkt genom en pekare i inbyggd kod. Detta kan spara lite problem och omkostnader vid marschering mellan Java och ursprunglig representation av data.
JNI-gränssnittet definierar flera funktioner för att hantera direktbyte-buffertar: NIO Support .