Recherche…


Introduction

La classe ByteBuffer été introduite dans java 1.4 pour faciliter le travail sur les données binaires. Il est particulièrement adapté pour être utilisé avec des données de type primitif. Il permet la création, mais aussi la manipulation ultérieure d'un byte[] s sur un niveau d'abstraction plus élevé

Syntaxe

  • octet [] arr = nouvel octet [1000];
  • ByteBuffer buffer = ByteBuffer.wrap (arr);
  • ByteBuffer buffer = ByteBuffer.allocate (1024);
  • ByteBuffer buffer = ByteBuffer.allocateDirect (1024);
  • octet b = buffer.get ();
  • octet b = buffer.get (10);
  • short s = buffer.getShort (10);
  • buffer.put ((octet) 120);
  • buffer.putChar ('a');

Utilisation de base - Création d'un ByteBuffer

Il existe deux manières de créer un ByteBuffer , où l’on peut subdiviser à nouveau.

Si vous avez un byte[] existant byte[] , vous pouvez l’ emballer dans un ByteBuffer pour simplifier le traitement:

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

Ce serait une possibilité pour le code qui gère les interactions de réseau de bas niveau


Si vous ne disposez pas d'un byte[] existant byte[] , vous pouvez créer un ByteBuffer sur un tableau spécifiquement alloué au tampon, comme ceci:

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

Si le chemin de code est extrêmement critique et que vous avez besoin d' un accès direct à la mémoire du système , le ByteBuffer peut même allouer des tampons directs à l' aide de #allocateDirect()

Utilisation de base - Écrire des données dans le tampon

Étant donné un ByteBuffer exemple , on peut écrire des données de type primitif à l'aide relative et absolue put . La différence frappante est que le fait de mettre des données en utilisant la méthode relative garde la trace de l'index auquel les données sont insérées pour vous, alors que la méthode absolue exige toujours de donner un index pour put les données.

Les deux méthodes permettent de "chaîner" les appels. Étant donné un tampon de taille suffisante, on peut faire ce qui suit:

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

ce qui équivaut à:

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

Notez que la méthode fonctionnant sur les byte n'est pas nommée spécialement. En outre noter qu'il est également valide pour passer à la fois un ByteBuffer et un byte[] pour put . A part cela, tous les types primitifs ont des méthodes de put spécialisées.

Une note supplémentaire: L'index donné lors de l'utilisation de put* absolu put* est toujours compté en byte s.

Utilisation de base - Utilisation de DirectByteBuffer

DirectByteBuffer est une implémentation spéciale de ByteBuffer qui ne comporte aucun byte[] dessous.

Nous pouvons allouer un tel ByteBuffer en appelant:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(16);

Cette opération allouera 16 octets de mémoire. Le contenu des tampons directs peut résider en dehors du tas normal récupéré.

Nous pouvons vérifier si ByteBuffer est direct en appelant:

directBuffer.isDirect(); // true

Les principales caractéristiques de DirectByteBuffer sont que JVM essaiera de travailler en mode natif sur la mémoire allouée sans mise en mémoire tampon supplémentaire, de sorte que les opérations effectuées sur celui-ci peuvent être plus rapides que celles effectuées sur ByteBuffer avec des tableaux situés en dessous.

Il est recommandé d'utiliser DirectByteBuffer avec des opérations d'E / S lourdes reposant sur la vitesse d'exécution, comme la communication en temps réel.

Nous devons être conscients que si nous essayons d'utiliser la méthode array() , nous obtiendrons une UnsupportedOperationException . Il est donc recommandé de vérifier si notre ByteBuffer l’a (tableau d’octets) avant d’essayer d’y accéder:

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

Une autre utilisation du tampon d'octet direct est l'interopérabilité via JNI. Comme un tampon d'octet direct n'utilise pas d' byte[] , mais un bloc de mémoire réel, il est possible d'accéder à cette mémoire directement via un pointeur en code natif. Cela permet d’économiser un peu de temps et d’encombrement lors de la répartition entre Java et la représentation native des données.

L'interface JNI définit plusieurs fonctions pour gérer les tampons d'octets directs: Support NIO .



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow