Quelle est l’utilisation de ByteBuffer en Java?

Quels sont les exemples d’applications pour un ByteBuffer en Java? Veuillez énumérer tous les exemples de scénarios où cela est utilisé. Je vous remercie!

C’est une bonne description de ses utilisations et de ses lacunes. Vous l’utilisez essentiellement chaque fois que vous devez effectuer des E / S rapides de bas niveau. Si vous alliez implémenter un protocole TCP / IP ou si vous écriviez une firebase database (SGBD), cette classe serait utile.

La classe ByteBuffer est importante car elle constitue une base pour l’utilisation des canaux en Java. La classe ByteBuffer définit six catégories d’opérations sur les tampons d’octets:

  • Les méthodes get et put absolues et relatives qui lisent et écrivent des octets simples;

  • En vrac relatif, obtenez des méthodes qui transfèrent des séquences contiguës d’octets de ce tampon dans un tableau;

  • Les méthodes de mise en masse relatives qui transfèrent des séquences contiguës d’octets d’un tableau d’octets ou d’un autre tampon d’octets dans ce tampon;

  • Les méthodes get et put absolues et relatives qui lisent et écrivent les valeurs d’autres types primitifs, en les traduisant vers et à partir de séquences d’octets dans un ordre d’octet particulier;

  • Méthodes de création de tampons de vue, qui permettent à un tampon d’octets d’être considéré comme un tampon contenant des valeurs d’un autre type primitif; et

  • Méthodes de compactage , de duplication et de découpage d’ un tampon d’octets.

Example code : Putting Bytes into a buffer.

  // Create an empty ByteBuffer with a 10 byte capacity ByteBuffer bbuf = ByteBuffer.allocate(10); // Get the buffer's capacity int capacity = bbuf.capacity(); // 10 // Use the absolute put(int, byte). // This method does not affect the position. bbuf.put(0, (byte)0xFF); // position=0 // Set the position bbuf.position(5); // Use the relative put(byte) bbuf.put((byte)0xFF); // Get the new position int pos = bbuf.position(); // 6 // Get remaining byte count int rem = bbuf.remaining(); // 4 // Set the limit bbuf.limit(7); // remaining=1 // This convenience method sets the position to 0 bbuf.rewind(); // remaining=7 

Java IO utilisant des API orientées stream est exécuté en utilisant un tampon comme stockage temporaire de données dans l’espace utilisateur. Les données lues à partir du disque par DMA sont d’abord copiées dans des tampons dans l’espace du kernel, qui sont ensuite transférés dans la mémoire tampon de l’espace utilisateur. Il y a donc des frais généraux. En évitant cela, on peut obtenir un gain de performance considérable.

Nous pourrions ignorer ce tampon temporaire dans l’espace utilisateur, s’il y avait un moyen d’accéder directement au tampon dans l’espace du kernel. Java NIO permet de le faire.

ByteBuffer fait partie des tampons fournis par Java NIO. C’est juste un conteneur ou un réservoir de stockage pour lire des données ou écrire des données. Le comportement ci-dessus est obtenu en allouant un tampon direct à l’aide de l’API allocateDirect() sur Buffer.

La documentation Java de Byte Buffer contient des informations utiles.

Dans Android, vous pouvez créer un tampon partagé entre C ++ et Java (avec la méthode directAlloc) et le manipuler des deux côtés.

Voici un excellent article expliquant les avantages de ByteBuffer. Voici les points clés de l’article:

  • Le premier avantage d’un ByteBuffer, qu’il soit direct ou indirect, est un access aléatoire efficace à des données binarys structurées (par exemple, des E / S de bas niveau, comme indiqué dans l’une des réponses). Avant Java 1.4, pour lire de telles données, on pouvait utiliser un DataInputStream, mais sans access aléatoire.

Les avantages suivants sont spécifiques à ByteBuffer / MappedByteBuffer direct. Notez que les tampons directs sont créés en dehors du tas:

  1. Non affecté par les cycles gc : les tampons directs ne seront pas déplacés lors des cycles de nettoyage de la mémoire car ils résident en dehors du segment de mémoire. La technologie de mise en cache BigMemory de TerraCota semble largement s’appuyer sur cet avantage. S’ils étaient en tas, cela ralentirait les temps de pause gc.

  2. Augmentation des performances : dans les stream IO, les appels en lecture impliqueraient des appels système, qui nécessiteraient un basculement de contexte entre l’utilisateur et le mode kernel et vice-versa, ce qui serait coûteux surtout si le fichier est constamment utilisé. Cependant, avec le mappage de mémoire, ce changement de contexte est réduit car les données sont plus susceptibles d’être trouvées dans la mémoire (MappedByteBuffer). Si des données sont disponibles en mémoire, elles sont directement accessibles sans invoquer de système d’exploitation, c’est-à-dire sans changement de contexte.

Notez que les MappedByteBuffers sont très utiles, surtout si les fichiers sont volumineux et que peu de groupes de blocs sont utilisés plus fréquemment.

  1. Partage de pages : les fichiers mappés en mémoire peuvent être partagés entre les processus lorsqu’ils sont alloués dans l’espace de mémoire virtuelle du processus et peuvent être partagés entre les processus.