1: Bufferedwriter
1. Introduction aux fonctions de classe:
BufferedWriter, flux de sortie de caractères de cache, sa fonction est de fournir une fonction de cache pour le flux de sortie de caractères sous-jacent entrant. De même, lorsque vous utilisez le flux de sortie de caractères sous-jacent pour écrire des caractères ou des tableaux de caractères vers la destination, la connexion à la destination doit être ouverte à chaque fois qu'il est écrit. Un tel accès fréquent est constamment efficace et peut également causer certains dommages au milieu de stockage. Par exemple, lorsque nous écrivons constamment des octets sur le disque, il est exagéré d'écrire une très grande unité de G à un fichier spécifié sur le disque, et si nous n'écrivons pas un octet, le canal sur ce disque doit être ouvert une fois. Ce résultat est sans aucun doute terrifiant. , et lorsque nous utilisons BufferedWriter pour envelopper le flux de sortie de caractères sous-jacent, tel que FileReader, nous pouvons d'abord écrire les caractères à écrire dans le fichier du programme dans l'espace de cache intégré du BufferedWriter, puis lorsqu'un certain montant sera atteint, il sera écrit dans le flux FileReader en même temps. À l'heure actuelle, FileReader peut ouvrir un canal et écrire ce bloc de données dans le fichier. Bien qu'il soit impossible d'obtenir l'effet de l'écriture de toutes les données sur le disque en un seul accès, il améliore également considérablement l'efficacité et réduit le nombre d'accès au disque! C'est sa signification. Son principe de travail spécifique est brièvement mentionné ici: il peut être assez déroutant ici. Vous pouvez consulter le code source en détail. Si vous ne comprenez pas, regardez en arrière ici. Chaque fois que vous écrivez un caractère ou un tableau de caractères dans un tampon de tampon dans le programme, vous vérifierez si le tableau de caractères en cache BUF (la taille de BUF est par défaut ou spécifié lors de la création d'un BW, généralement la valeur par défaut est utilisée) est pleine. S'il n'est pas plein, les personnages sont écrits en buf. S'il est plein, l'écrivain sous-jacent (char [] b, int off, int est appelé. Len) Écrivez tous les caractères dans BUF à la sous-jacent sous-jacent en même temps, si le tableau de caractères est écrit, si le buf est plein, le même que le traitement lorsqu'il est plein ci-dessus, si le tableau écrit peut être stocké, alors stockez-le dans Buf, si les caractères sont storés, et le nombre de personnages à être écrits pour Buf est que le Buf, et le nombre de caractères à être écrit pour Buf, alors que le nombre de caractères est à Buf, et le nombre de personnages à être écrits, Dans BUF pour être écrit, puis stocker les caractères à écrire en buf (stockage de l'indice 0), si les caractères à écrire dépassent la longueur de BUF, alors écrivez directement sur,
2. Introduction à l'API BufferedWriter:
R: écrivain privé de mot-clé; Stream de sortie de caractères inférieur Char Private CB []; Tampon Array Private Int nchars, NextChar; NCHARS - SIZE DE LA TAILLE DE NCHARS, NEXTCHAR --SUBScript du caractère suivant dans CB Private Static int defaultCharbucheSize = 8192; SIGNE CB TIME CB par défaut STACK-SACKETATOR; Caractère Newline, utilisé pour la méthode Newline. Différentes plates-formes ont des valeurs différentes. B: Construire la méthode BufferedWriter (écrivain out) Crée BufferedWriter BW en utilisant la taille CB par défaut. BufferedWriter (écrivain out, int sz) crée BufferedWriter BW en utilisant la taille CB par défaut. C: La méthode générale void close () ferme ce flux et libère des ressources liées à ce flux. Void FlushBuffer () rincera les personnages en cache dans CB dans le sous-jacent, Void Flush () rafraîchit ce flux et rafraîchit le flux sous-jacent Void Newline () écrit un personnage de Newline. Void Write (INT C) écrit un seul personnage dans CB. void write (char cbuf [], int off, int len) écrire une longueur de caractère de len de l'indice off à cb void write (String s, int off, int len) écrivez une partie d'une chaîne à CB
3. Analyse du code source
package com.chy.io.original.code; import java.io.ioexception; import java.io.printwriter; / ** * fournir une fonction tampon pour les flux de sortie de caractères et améliorer l'efficacité. Vous pouvez utiliser le caractère spécifié pour tamponner la taille du tableau ou le caractère par défaut pour tamponner la taille du tableau. * / classe publique BufferedWriter étend l'écrivain {// Base Array Private Writer Out; // Tampon Array Private Char CB []; // NCHARS - Le nombre total de caractères dans CB, NextChar - L'indice du caractère suivant dans CB Private Int Nchars, NextChar; // par défaut cb size private static int defaultCharbucheSize = 8192; / ** * chaîne de séparateur de ligne. Il s'agit de la valeur de la propriété line.separator * au moment où le flux a été créé. * Caractère Newline Line, utilisé pour la méthode Newline. Différentes plates-formes ont des valeurs différentes. * / STRING STRING STRING SECARTOR; / ** * Créer BufferedWriter BW avec la taille CB par défaut. * / public BufferedWriter (écrivain out) {this (out, defaultCharbucheSize); } / ** * Créer BR et initialiser les champs associés avec la taille CB spécifiée * / publique BufferedWriter (écrivain Out, int sz) {super (out); if (sz <= 0) lance un nouveau IllégalArgumentException ("Taille de tampon <= 0"); this.out = out; cb = new char [sz]; nchars = sz; nextchar = 0; // obtient la représentation des caractères Newline sous différentes plates-formes. LigneSeSarator = (String) Java.Security.AccessController.Doprivileged (new Sun.Security.Action.getPropertyAction ("line.separator")); } / ** détecter si le flux de sortie de caractères sous-jacent est fermé * / private void assureOpen () lève ioException {if (out == null) lancez new ioException ("Stream fermé"); } / ** * rincer les personnages en cache dans CB à la sous-jacent, mais ne pas rincer les personnages en sous-jacent. * Et Clair CB. * / void FlushBuffer () lève ioException {synchronisé (lock) {assureOpen (); if (nextchar == 0) return; out.write (CB, 0, NextChar); NextChar = 0;}} / ** * Écrivez un seul caractère à CB. * / public void write (int c) lève ioException {synchronisé (lock) {assureOpen (); if (nextchar> = nchars) flushbuffer (); CB [NextChar ++] = (char) c;}} / ** * Notre propre méthode Little Min, pour éviter de charger java.lang.math si nous avons exécuté * des descripteurs de fichiers et nous essayons d'imprimer une trace de pile. * / privé int min (int a, int b) {if (a <b) return a; return b; } / ** * Écrivez une longueur de caractère de Len de l'indice OFF à CB * / public void write (char cbuf [], int off, int len) lève ioException {synchronisé (lock) {assureOpen (); if ((off <0) || (off> cbuf.length) || (len <0) || ((off + len)> cbuf.length) || ((off + len) <0)) {lancer une nouvelle indexoutofboundSexception (); } else if (len == 0) {return; } if (len> = nchars) {/ * si Len est supérieur à la longueur de CB, les caractères existants de CB et les caractères de CBUF sont directement écrits à Out, au lieu d'écrire à CB, puis d'écrire à la sortie. * / flushbuffer (); out.write (cbuf, off, len); retour; } int b = off, t = off + len; while (b <t) {int d = min (nchars - nextchar, t - b); system.arraycopy (cbuf, b, cb, nextchar, d); b + = d; nextchar + = d; if (nextchar> = nchars) flushbuffer (); }}} / ** * Écrivez la partie d'une chaîne à CB * / public void write (String s, int off, int len) lève ioException {synchronisé (lock) {assureOpen (); int b = off, t = off + len; while (b <t) {int d = min (nchars - nextchar, t - b); s.getchars (b, b + d, cb, nextchar); b + = d; nextchar + = d; if (nextchar> = nchars) flushbuffer (); }}} / ** * Écrivez une nouvelle ligne. * / public void newline () lève ioException {write (lineSparator); } / ** * Rafraîchissez ce flux et rafraîchissez le flux sous-jacent en même temps * / public void flush () lève ioException {synchronisé (lock) {flushBuffer (); out.flush ();}} / ** * Fermez ce flux et publiez des ressources liées à ce flux. * / public void close () lève ioException {synchronisé (lock) {if (out == null) {return; } essayez {FlushBuffer (); } enfin {out.close (); out = null; cb = null; }}}}4. Exemple de démonstration: utilisez le BufferedReader suivant pour implémenter la copie des fichiers de type caractéristique.
Deux: BufferedReader
1. Introduction aux fonctions de classe:
Flux d'entrée de caractères tamponné, sa fonction est de fournir une fonction tampon pour le flux d'entrée de caractères sous-jacent entrant. Il lira les caractères du flux d'entrée de caractères sous-jacent (IN) dans son propre tampon (tableau de caractères mis en cache intégré), puis le programme appelle la méthode de lecture du BufferedReder pour lire les caractères du tampon dans le programme. Lorsque les caractères du tampon sont lus, le BufferedReader lira le prochain bloc de données de dans et dans le tampon pour que le programme se lise jusqu'à la lecture des données In In. Les avantages de cela sont, d'abord, il améliore l'efficacité de lecture, et deuxièmement, il réduit le nombre de connexions pour ouvrir le support de stockage. Pour des raisons détaillées, BufferedWriter mentionné ci-dessous. Il existe une méthode clé Fill (), qui est de remplir les données de l'IN et de remplir les données du tampon chaque fois que les données du tampon sont lues dix fois plus rapidement que celle ne se lit du disque! Il s'agit d'une amélioration très terrifiante de l'efficacité. Dans le même temps, nous ne pouvons pas spécifier la taille du tampon du BufferedReader sans interdire. Après tout, il faut beaucoup de temps pour lire en pavage. Deuxièmement, le prix de la mémoire est relativement cher. Ce que nous pouvons faire, c'est essayer de trouver des points raisonnables. Généralement, nous n'avons pas à nous en soucier et à utiliser la taille par défaut du tampon lors de la création d'un BufferedReader.
2. Introduction à l'API BufferedReader:
R: Construction de la méthode BufferedReader (Reader IN, int sz) Crée un BufferedReader basé sur la taille spécifiée et le flux d'entrée de caractères sous-jacent. br BufferedReader(Reader in) Use the default size to create the buffered stream of the underlying output stream B: General method void close() close this stream and release all resources related to this stream void mark(int readAheadLimit) mark the position of this stream at this time boolean markSupported() determines whether this stream supports marking void reset() reset in reset in the position of the last mark boolean ready() determines whether this stream can Les caractères de lecture int lisent () lit un seul caractère et revient sous une forme entière. Si la fin de In est lue, elle revient -1. int lic (char [] cbuf, int off, int len) lire les caractères len dans cbuf à partir de l'indice off, longueur len string readline () lire une ligne skip long (long n) rejette n caractères dans cbuf
3. Analyse du code source
package com.chy.io.original.code; import java.io.ioexception; / ** * Ajouter un tableau CB tampon de caractères pour le flux d'entrée de caractères sous-jacent. Améliorer l'efficacité * @version 1.1, 13/11/17 * @Authorandychen * / classe publique BufferedReader étend le lecteur {lecteur privé dans; Char privé CB []; Int nchars privé, Nextchar; Final statique privé int invalidé = -2; Final statique privé int non marqué = -1; private int markedchar = non marqué; private int ReadaHeadlimit = 0; / * Valide uniquement lorsque MarkedChar> 0 * / / ** Si le caractère suivant est un flux de ligne, sautez-le * / Boolean privé skiplf = false; / ** l'indicateur skiplf lorsque la marque a été définie * / booléen privé markedSkiplf = false; private static int defaultCharbucheSize = 8192; private static int defaultExpectedLeleNthength = 80; / ** * Créez un BufferedReader basé sur la taille spécifiée et le flux d'entrée de caractères sous-jacent. Br * / public BufferedReader (lecteur dans, int sz) {super (in); if (sz <= 0) lance un nouveau IllégalArgumentException ("Taille de tampon <= 0"); this.in = in; cb = new char [sz]; NextChar = nchars = 0; } / ** * Utilisez la taille par défaut pour créer un flux tamponné du flux de sortie sous-jacent * / public BufferedReader (Reader in) {this (in, defaultCharbucheSize); } / ** détecter si le flux d'entrée de caractères sous-jacent dans est fermé * / private void assureOpen () lève ioException {if (in == null) lance une nouvelle ioException ("Stream fermé"); } / ** * Remplissez CB. * / private void fill () lève ioException {int dst; if (markedchar <= non marqué) {/ * no mark * / dst = 0;} else {/ * marqué * / int delta = nextchar - markedchar; if (delta> = readaHeadlimit) {/ * dépassé la limite de lecture: invalider mark * / markedchar = invalidé; ReadaHeadlimit = 0; dst = 0; } else {if (readaHeadlimit <= cb.length) {/ * shuffle dans le tampon actuel * / System.ArrayCopy (CB, MarkedChar, CB, 0, Delta); MarkedChar = 0; dst = delta;} else {/ * reallocate tamper pour accueillir la limite de lecture * / char ncb [] = new char [readaheadlimit]; System.ArrayCopy (CB, Markedchar, NCB, 0, Delta); CB = NCB; MarkedChar = 0; dst = delta;} nextChar = nchars = delta; }} int n; do {n = in.read (cb, dst, cb.length - dst);} while (n == 0); if (n> 0) {nchars = dst + n; NextChar = dst;}} / ** * Lisez un seul caractère et retournez comme un entier. Si la fin de In est lue, elle revient -1. * / public int read () lève ioException {synchronisé (lock) {assureOpen (); pour (;;) {if (nextChar> = nchars) {fill (); if (nextChar> = nchars) return -1;} if (skiplf) {skiplf = false; if (cb [nextChar] == '/ n') {NextChar ++; Continuer; }} return CB [NextChar ++]; }} } /** * Read len characters in in to cbuf from the length len starting from the subscript off*/ private int read1(char[] cbuf, int off, int len) throws IOException {if (nextChar >= nChars) { /* If the requested length is at least as large as the buffer, and if there is no mark/reset activity, and if line feeds are not being skipped, do not both to copy the characters dans le tampon local. De cette façon, les ruisseaux tamponnés vont cascade sans danger. * / if (len> = cb.length && markedchar <= non marqué &&! skiplf) {return in.read (cbuf, off, len); } fill ();} if (nextchar> = nchars) return -1; if (skiplf) {skiplf = false; if (cb [nextChar] == '/ n') {nextChar ++; if (nextChar> = nchars) fill (); if (nextchar> = nchars) return -1; }} int n = math.min (len, nchars - nextchar); System.ArrayCopy (CB, nextChar, cbuf, off, n); NextChar + = n; return n; } / ** * Lire les caractères Len In dans CBUF à Longueur Len de l'index OFF de l'indice OFF * / public int lien (char cbuf [], int off, int len) lève ioException {synchronisé (lock) {assureOpen (); if ((off <0) || (off> cbuf.length) || (len <0) || ((off + len)> cbuf.length) || ((off + len) <0)) {lancer une nouvelle indexoutofboundSexception (); } else if (len == 0) {return 0; } int n = read1 (cbuf, off, len); if (n <= 0) return n; while ((n <len) && in.ready ()) {int n1 = read1 (cbuf, off + n, len - n); if (n1 <= 0) casser; n + = n1; } return n;}} / ** * Lire une ligne à partir de la ligne IN et ignorez les pauses * / string readline (boolean ignorelf) lance ioException {stringBuffer s = null; int startCarch; synchronisé (verrouillage) {assureOpen (); booléen omitlf = ignorant || skiplf; bufferloop: for (;;) {if (nextChar> = nchars) fill (); if (nextChar> = nchars) {/ * eof * / if (s! = null && s.Length ()> 0) return s.toString (); elsereturn null;} boolean eol = false; char c = 0; int i; / * Sauter un restes '/ n', si nécessaire * / if (omitlf && (cb [nextChar] == '/ n')) nextchar ++; skiplf = false; omitlf = false; charloop: for (i = nextchar; i <nchars; i ++) {c = cb [i]; if ((c == '/ n') || (c == '/ r')) {eol = true; Break Charloop; }} startChar = nextChar; nextChar = i; if (eol) {String str; if (s == null) {str = new String (cb, startChar, i - startChar); } else {s.append (cb, startChar, i - startchar); str = s.toString (); } NextChar ++; if (c == '/ r') {skiplf = true; } return str;} if (s == null) s = new StringBuffer (defaultExpectedLeleNthength); s.append (cb, startchar, i - startchar); }}} / ** * Lire une ligne depuis, * / public String readLine () lève ioException {return readLine (false); } / ** * Décarner n caractères dans * / public long skip (long n) lève ioException {if (n <0l) {throw new illégalargumentException ("la valeur de skip est négative");} synchronisé (lock) {assureOpen (); long r = n; while (r> 0) {if (nextChar> = nchars) fill (); if (nextChar> = nchars) / * eof * / break; if (skiplf) {skiplf = false; if (cb [nextchar] == '/ n') {nextChar ++; }} long d = nchars - nextChar; if (r <= d) {nextChar + = r; r = 0; Break;} else {r - = d; NextChar = nChars;}} return n - r;}} / ** * Déterminez si CB est vide ou s'il y a des caractères lisibles dans le sous-jacent. * / public boolean ready () lance ioException {synchronisé (lock) {assureOpen (); / * * Si Newline doit être ignorée et que le prochain char à lire * est un personnage de Newline, alors sautez-le tout de suite. * / if (skiplf) {/ * Notez que in.ready () reviendra true si et seulement si la prochaine * lecture sur le flux ne bloque pas. * / if (nextchar> = nchars && in.ready ()) {fill ();} if (nextchar <nchars) {if (cb [nextchar] == '/ n') nextchar ++; skiplf = false;}} return (nextchar <nchars) || in.ready ();}} / ** * Déterminez si ce flux prend en charge les marques * / public boolean markSupported () {return true; } / ** * Marquez la position de ce flux pour le moment et permettez à la lecture des caractères ReadaHeadlimit avant l'échec de la méthode de réinitialisation. * / public void mark (int ReadaHeadlimit) lève ioException {if (readaHeadlimit <0) {lancez new illégalargumentException ("Lire-ahead limit <0");} synchronisé (Lock) {assureOpen (); this.readaheadlimit = readaheadlimit; MarkedChar = NextChar; markedSkiPlf = skiplf;}} / ** * réinitialisez la position où il a été marqué pour la dernière fois. Autrement dit, le personnage suivant est lu à partir de la position qui est marquée pour la dernière fois. * / public void reset () lève ioException {synchronisé (lock) {assureOpen (); si (markedchar <0) lance un nouvel ioException ((markedchar == invalidé)? "Mark invalid": "Stream Not Marked"); NextChar = MarkedChar; skiplf = markedSkiPlf;}} // Fermez ce flux et libérez toutes les ressources liées à ce flux public void close () lance ioException {synchronisé (lock) {if (in == null) return; joindre(); in = null; cb = null;}}}4. Exemple de démonstration:
Package com.chy.io.original.test; import java.io.bufferedeader; import java.io.boperedwriter; importer java.io.file; import java.io.fileReader; import java.io.filewriter; publication java.io.filewer; {/ ** * Le test de ces deux classes ici est relativement simple, qui est d'envelopper le flux de caractères de fichier et d'implémenter la copie du fichier * Si vous êtes intéressé, vous pouvez tester l'efficacité, être paresseux, et l'ignorer * / public static void main (String [] args) lance ioexception {file resoucefile = nouveau fichier ("d: //test.txt"); File ("e: //copopyoftest.txt"); buffereDaDer br = new bufferedReader (new fileReader (resoucefile)); bufferedwriter bw = new buffredwriter (new filewriter (cibleFile)); char [] cbuf = new Char [1024]; int n = 0; while (n = br.read (cbuf)! = -1) {bw.write (cbuf, 0, n);} // N'oubliez pas de rafraîchir et de fermer le flux, sinon les ressources ne seront pas libérées dans le temps d'une part, et d'autre part, cela peut entraîner une perte de données si br.close (); bw.flush (); bw.close ();}}Résumer:
Pour BufferedReader et BufferedWriter, l'essence consiste à ajouter une fonction tampon au flux d'entrée et de sortie de caractères sous-jacent, d'abord lire ou écrire des données dans le flux sous-jacent sous la forme d'un groupe de lectures à la fois, puis d'opérer sur le tampon. Cela non seulement l'efficacité, mais aussi les ressources. Enfin, dans le programme, pour des raisons d'efficacité, ces deux classes doivent être utilisées pour que des flux de bas niveau les décorent, au lieu de simplement tenir le flux et les télécharger directement, pensant qu'ils peuvent être réalisés.