À côté de l'article précédent, nous continuerons à apprendre les opérations de flux d'octets en Java.
Décorateur tamponné de flux tamponné en avant / sortie
Le flux décorateur est en fait un flux IO de fichiers basé sur un motif de conception "Mode décorateur", et notre flux de tampon n'est que l'un d'eux. Jetons un coup d'œil.
Avant cela, nous avons utilisé Fichier Read and Write Streams FileInputStream et FileOutputStream Lire et écriture à partir d'octets de disque ou d'octets, ce qui prend beaucoup de temps.
Notre flux de tampon peut prévoir le nombre d'octets d'une capacité spécifiée du disque à la fois en mémoire, et les opérations de lecture suivantes seront lues directement à partir de la mémoire pour améliorer l'efficacité. Jetons un coup d'œil à l'implémentation spécifique des flux tamponnés:
Prenons d'abord à TamperedInputStream comme exemple, mentionnons brièvement ses propriétés principales:
BUF est un tableau d'octets utilisé pour tamponner les lectures. Sa valeur sera remplie en continu lorsque le flux est lu, et les opérations de lecture ultérieures peuvent être directement basées sur ce tableau tamponné.
Default_Buffer_Size Spécifie la taille du tampon par défaut, c'est-à-dire la longueur du tableau de BUF. Max_buffer_size spécifie la limite supérieure du tampon.
Le nombre pointe vers le dernier indice d'octet valide dans le tableau tamponné. POS pointe vers la position d'index d'octet suivant à lire.
Markpos et Marklimit sont utilisés pour répéter les opérations de lecture.
Ensuite, jetons un coup d'œil à plusieurs exemples de constructeurs de BufferedInputStream:
public BufferedInputStream (InputStream in) {this (in, default_buffer_size);} Public BufferedInputStream (InputStream in, int size) {super (in); if (size <= 0) {lancer un nouveau IllégalArgumentException ("Taille du tampon <= 0"); } buf = nouveau octet [taille];}Dans l'ensemble, le premier n'a besoin que de passer dans une instance InputStream qui est "décorée" et d'utiliser un tampon de taille par défaut. Ce dernier peut indiquer explicitement la taille du tampon.
De plus, Super (in) enregistre cette instance InputStream dans le champ d'attribut In de la classe Parent FilterInputStream, et toutes les opérations de lecture de disque réelles sont émises par cette instance InputStream.
Jetons un coup d'œil aux opérations de lecture les plus importantes et à la façon dont le tampon est rempli.
public synchronisé int lien () lève ioException {if (pos> = count) {fill (); if (pos> = count) return -1; } return getBuFipen () [pos ++] & 0xff;}Je crois que tout le monde connaît déjà cette méthode. Il lit l'octet suivant du flux et le renvoie, mais l'implémentation en détail est encore légèrement différente.
Le nombre pointe vers la position suivante de l'indice d'octet valide dans le tableau tamponné, et POS pointe vers la position suivante de l'indice d'octet à lire. En théorie, le POS ne peut pas être supérieur au nombre, tout au plus égal à.
Si POS est égal au nombre, cela signifie que tous les octets valides du tableau tampon ont été lus. À l'heure actuelle, les données "inutiles" dans le tampon doivent être jetées et un lot de nouvelles données est rechargé du disque pour remplir le tampon.
En fait, la méthode de remplissage est ce qu'elle fait. Il a beaucoup de code, donc je ne vous emmènerai pas pour l'analyser. Si vous comprenez sa fonction, il est probablement facile d'analyser sa mise en œuvre.
Si POS est toujours égal au nombre après l'appel de la méthode de remplissage, cela signifie que l'instance InputStream n'a lu aucune donnée du flux, c'est-à-dire qu'il n'y a pas de données dans le flux de fichiers à lire. Pour cela, voir la ligne 246 de la méthode de remplissage.
En général, si le tampon est rempli avec succès, notre méthode de lecture prendra un octet directement dans le tampon et le retournera à l'appelant.
Public synchronisé int lien (byte b [], int off, int len) {// .....}Cette méthode est également une "connaissance", n'a plus d'explication inutile, la mise en œuvre est similaire.
La méthode Skip est utilisée pour ignorer le nombre d'octets d'une longueur spécifiée pour la lecture continue du flux de fichiers:
Skip long synchronisé public (long n) {// ......}Une chose à noter est que la méthode Skip essaie de sauter n octets, mais il n'est pas garanti de sauter n octets. La méthode renvoie le nombre réel d'octets sautés. Si le nombre restant d'octets disponibles dans le tableau tamponné est inférieur à N, le nombre réel d'octets qui peuvent être sautés dans le réseau tamponné seront finalement ignorés.
Enfin, parlons de cette méthode étroite:
public void close () lève ioException {byte [] tampon; while ((buffer = buf)! = null) {if (bufupDater.compareAndset (this, buffer, null)) {inputStream input = in; in = null; if (input! = null) input.close (); retour; } // else réessayer au cas où un nouveau buf aurait été enveloppé en remplissage ()}}La méthode étroite videra le flux "décoré" et appellera sa méthode proche pour libérer les ressources pertinentes, qui finiront par effacer l'espace mémoire occupé par le tableau de tampon.
BufferedInputStream fournit des capacités de tampon de lecture, tandis que BufferedOutputStream fournit des capacités de tampon d'écriture, c'est-à-dire que les opérations d'écriture de mémoire ne seront pas mises à jour immédiatement sur le disque et seront temporairement enregistrées dans le tampon et seront écrites ensemble lorsque le tampon sera plein.
octet protégé buf []; Count int protégé;
BUF représente le tampon interne, et le nombre représente la capacité de données réelle dans le tampon, c'est-à-dire le nombre d'octets efficaces dans BUF, plutôt que la longueur du réseau BUF.
public BufferedOutputStream (outputStream out) {this (out, 8192);} public buffredOutputStream (outputStream out, int size) {super (out); if (size <= 0) {lancer un nouveau IllégalArgumentException ("Taille du tampon <= 0"); } buf = nouveau octet [taille];}Avec la même idée d'implémentation, il est nécessaire de fournir une instance de flux de sortie OutputStream, et il peut également indiquer sélectivement la taille du tampon.
public synchronisé void write (int b) lève ioException {if (count> = buf.length) {flushBuffer (); } buf [count ++] = (byte) b;}La méthode d'écriture vérifiera d'abord si le tampon peut encore s'adapter à cette opération d'écriture. Si une opération d'écriture de disque ne peut pas être lancée, toutes les données de tampon seront écrites dans le fichier de disque, sinon le tampon sera d'abord écrit dans le tampon.
Bien sûr, BufferedOutputStream fournit également une méthode Flush pour fournir une interface à l'extérieur, c'est-à-dire que vous n'avez pas à attendre que le tampon soit plein avant d'écrire des données sur le disque. Vous pouvez également appeler explicitement cette méthode pour effacer le tampon et mettre à jour les fichiers de disque.
Le public synchronisé void flush () lève ioException {FlushBuffer (); out.flush ();}En ce qui concerne les flux tamponnés, le contenu de base est introduit comme ci-dessus. Il s'agit d'un flux qui peut améliorer considérablement l'efficacité. Grâce à lui, le nombre d'accès au disque peut être réduit et l'efficacité d'exécution du programme peut être améliorée.
Nous ne discuterons pas du Stream de sérialisation d'objet ObjectInput / OutputStream et du Decorator Stream DataRainput / OutputStream basé sur les types de base. Lorsque nous apprenons la sérialisation, nous discuterons à nouveau de ces deux flux d'octets.
Tous les codes, images et fichiers de l'article sont stockés dans le cloud sur mon github:
(https://github.com/singleyam/overview_java)
Vous pouvez également choisir de télécharger localement.
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.