Quelle est l'utilisation de ByteBuffer en Java? [fermé]

199

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

Aklin
la source
1
La compression d'Apache Hadoop (codec zlib par exemple) utilise ByteBuffer de jave.nio.
nikk
Bon pour envoyer des données aux GPU.
Pixel

Réponses:

138

Il s'agit d'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 deviez implémenter un protocole TCP / IP ou si vous écriviez une base de données (SGBD), cette classe serait utile.

kelloti
la source
3
Est-il utile partout dans un site Web à fort trafic développé à l'aide de Java & Cassandra DB?
Aklin
1
Après une recherche rapide, il semble que oui, Cassandra utilise ByteBuffer: mail-archive.com/[email protected]/msg14967.html Si vous vous interrogez sur un site Web brut, il pourrait y en avoir, mais généralement ce n'est que va être utilisé indirectement par des sites Web - en utilisant des outils comme cassandra
kelloti
1
pas un mauvais lien, merci. voudrais ajouter celui-ci que j'ai trouvé utile - worldmodscode.wordpress.com/2012/12/14/…
Peter Perháč
Mauvais lien, j'ai peur ...
RoyalBigMack
96

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, comme indiqué dans la documentation Java 7 :

  • Méthodes get et put absolues et relatives qui lisent et écrivent des octets uniques;

  • Méthodes d' obtention en masse relative qui transfèrent des séquences contiguës d'octets de ce tampon dans un tableau;

  • Méthodes de mise en masse relative 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;

  • Méthodes get et put absolues et relatives qui lisent et écrivent des valeurs d'autres types primitifs, les traduisant vers et depuis des séquences d'octets dans un ordre d'octets particulier;

  • Méthodes de création de tampons d'affichage, qui permettent d'afficher un tampon d'octets 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
ykombinator
la source
56
la majeure partie de ce commentaire est copiée à partir des documents java 7 .
Janus Troelsen
6
À moins que vous ne profitiez d'un effet secondaire non évident, je pense que vous utilisez peut-être la mauvaise méthode pour un put absolu. Le Javadoc semble indiquer que le put absolu nécessite une valeur d'index.
Chuck Wolber
6
même s'il ne s'agit que d'une copie de l'api doc, même si son score bcs, certaines personnes semblent trop paresseuses pour y jeter un œil.
Chris
1
Il y a une erreur dans l'un des exemples. Le "put absolu", manque le premier paramètre qui représente l'indice (0 dans ce cas).
bvdb
21

Java IO utilisant des API orientées flux est effectué en utilisant un tampon comme stockage temporaire des données dans l'espace utilisateur. Les données lues sur le disque par DMA sont d'abord copiées dans des tampons dans l'espace noyau, qui sont ensuite transférées dans un tampon dans l'espace utilisateur. Il y a donc des frais généraux. L'éviter peut entraîner un gain de performances 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 noyau. Java NIO offre un moyen de le faire.

ByteBufferest parmi plusieurs tampons fournis par Java NIO. C'est juste un conteneur ou un réservoir pour lire ou écrire des données. Le comportement ci-dessus est obtenu en allouant un tampon direct à l'aide de l' allocateDirect()API sur le tampon.

La documentation Java de Byte Buffer contient des informations utiles.

deepujain
la source
14

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.

someUser
la source
13

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 accès aléatoire efficace aux données binaires structurées (par exemple, les entrées-sorties de bas niveau comme indiqué dans l'une des réponses). Avant Java 1.4, pour lire ces données, on pouvait utiliser un DataInputStream, mais sans accès aléatoire.

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

  1. Insensible aux cycles gc : les tampons directs ne seront pas déplacés pendant les cycles de récupération de place car ils résident en dehors du tas. La technologie de mise en cache BigMemory de TerraCota semble s'appuyer fortement sur cet avantage. S'ils étaient sur le tas, cela ralentirait les temps de pause gc.

  2. Amélioration des performances : dans le flux d'E / S, les appels en lecture impliqueraient des appels système, qui nécessitent un changement de contexte entre l'utilisateur et le mode noyau et vice versa, ce qui serait coûteux, surtout si le fichier est constamment consulté. 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 en mémoire (MappedByteBuffer). Si les données sont disponibles en mémoire, elles sont accessibles directement sans invoquer le système d'exploitation, c'est-à-dire sans changement de contexte.

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

  1. Partage de page : les fichiers mappés en mémoire peuvent être partagés entre les processus car ils sont alloués dans l'espace de mémoire virtuelle du processus et peuvent être partagés entre les processus.
Dheeru Mundluru
la source