web-dev-qa-db-fra.com

Quand utiliser le tableau d'octets et quand le tampon d'octets?

Quelle est la différence entre un tableau d'octets et un tampon d'octets?
De plus, dans quelles situations faut-il préférer l'un à l'autre?

[mon cas d'utilisation est pour une application web en cours de développement en Java].

59
Rajat Gupta

Il existe en fait plusieurs façons de travailler avec des octets. Et je suis d'accord qu'il n'est pas toujours facile de choisir le meilleur:

  • le byte[]
  • le Java.nio.ByteBuffer
  • le Java.io.ByteArrayOutputStream (en combinaison avec d'autres flux)
  • le Java.util.BitSet

Le byte[] Est juste un tableau primitif, contenant juste les données brutes. Il ne dispose donc pas de méthodes pratiques pour créer ou manipuler le contenu.

Un ByteBuffer ressemble plus à un constructeur. Il crée un byte[]. Contrairement aux tableaux, il propose des méthodes d'assistance plus pratiques. (par exemple, la méthode append(byte)). Ce n'est pas si simple en termes de tilisation . (La plupart des tutoriels sont beaucoup trop compliqués ou de mauvaise qualité, mais cela n vous mènera quelque part. Allez-vous plus loin? Puis lisez les nombreux pièges .)

Vous pourriez être tenté de dire qu'un ByteBuffer fait à byte[], Ce qu'un StringBuilder fait pour String. Mais il existe une différence/lacune spécifique de la classe ByteBuffer. Tout comme avec les tableaux, le ByteBuffer a une taille fixe. Donc, quand vous l'instanciez, vous devez déjà spécifier la taille de le tampon.

C'est l'une des raisons pour lesquelles je préfère souvent utiliser le ByteArrayOutputStream car il se redimensionne automatiquement, comme un ArrayList Est-ce que. (Il a une méthode toByteArray()). Parfois c'est pratique, pour l'envelopper dans un DataOutputStream. L'avantage est que vous aurez quelques appels de commodité supplémentaires, (par exemple writeShort(int) si vous devez écrire 2 octets.)

BitSet est utile lorsque vous souhaitez effectuer des opérations au niveau du bit. Vous pouvez obtenir/définir des bits individuels, et il a un opérateur logique des méthodes comme xor(). (La méthode toByteArray() a été introduite uniquement dans Java 7.)

Bien sûr, en fonction de vos besoins, vous pouvez les combiner pour créer votre byte[].

43
bvdb

ByteBuffer fait partie du nouveau package IO (nio) qui a été développé pour un débit rapide de données basées sur des fichiers. Plus précisément, Apache est un serveur Web très rapide (écrit en C) car il lit les octets. à partir du disque et les place directement sur le réseau, sans les mélanger via différents tampons. Il le fait via des fichiers mappés en mémoire, que les premières versions de Java ne possédaient pas. Avec l'avènement de nio, il est devenu possible d'écrire un serveur Web en Java c'est aussi rapide qu'Apache. Lorsque vous voulez un débit de fichier à réseau très rapide, alors vous voulez utiliser des fichiers mappés en mémoire et ByteBuffer.

Les bases de données utilisent généralement des fichiers mappés en mémoire, mais ce type d'utilisation est rarement efficace en Java. En C/C++, il est possible de charger une grande partie de la mémoire et de la convertir en données saisies que vous souhaitez. En raison du modèle de sécurité de Java, cela n'est généralement pas possible, car vous ne pouvez convertir que vers certains types natifs, et ces conversions ne sont pas très efficaces. ByteBuffer fonctionne mieux lorsque vous traitez uniquement des octets sous forme de données en octets simples - une fois que vous devez les convertir en objets, les autres classes Java io fonctionnent généralement mieux et sont plus faciles à utiliser).

Si vous ne traitez pas avec des fichiers mappés en mémoire, vous n'avez pas vraiment besoin de vous embêter avec ByteBuffer - vous utiliseriez normalement des tableaux d'octets. Si vous essayez de créer un serveur Web, avec le débit le plus rapide possible de données d'octets brutes basées sur des fichiers, alors ByteBuffer (en particulier MappedByteBuffer) est votre meilleur ami.

23
JRalph
3
bluefoot