Hoi! De les van vandaag zal voor het gemak in twee delen worden verdeeld. We zullen enkele oude onderwerpen herhalen die we eerder hebben besproken, en we zullen enkele nieuwe functies overwegen :) Laten we beginnen met de eerste. BufferedReaderJe hebt al zo vaak een klas gehad . Ik hoop dat je geen tijd hebt gehad om deze verklaring te vergeten:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Probeer voordat u verder leest te onthouden waar elk onderdeel - System.in, InputStreamReader, BufferedReader- verantwoordelijk voor is en waarom het nodig is. Weet je het nog? Zo niet, geen zorgen. :) Als je iets bent vergeten, herlees dan deze les , die is gewijd aan lezersklassen. We zullen kort herinneren aan wat elk van hen kan doen. System.in— dit is een stroom voor het ontvangen van gegevens van het toetsenbord.  In principe zou het alleen voldoende zijn om de logica te implementeren die nodig is om tekst te lezen. Maar, zoals u zich zult herinneren, System.inkan alleen bytes lezen, geen tekens:

public class Main {

   public static void main(String[] args) throws IOException { 

       while (true) { 
           int x = System.in.read(); 
           System.out.println(x); 
       } 
   } 
} 
Als we deze code uitvoeren en de Cyrillische letter "Й" invoeren, is de uitvoer:

Й
208
153
10 
Cyrillische tekens nemen 2 bytes in het geheugen in beslag en worden op het scherm weergegeven. Het getal 10 is de decimale weergave van een regelinvoerteken, dwz door op Enter te drukken. Het lezen van bytes is zo leuk, dus het gebruik System.inis niet erg handig. Om Cyrillische (en andere) letters correct te lezen, gebruiken we InputStreamReaderals omhulsel:

public class Main { 

   public static void main(String[] args) throws IOException { 

       InputStreamReader reader = new InputStreamReader(System.in); 
       while (true) { 
           int x = reader.read(); 
           System.out.println(x); 
       } 
   } 
} 
We voeren dezelfde letter "Й" in, maar het resultaat is deze keer anders:

Й 
1049 
10
InputStreamReaderconverteerde twee bytes (208 en 153) naar het enkele getal 1049. Dit is wat het betekent om karakters te lezen. 1049 komt overeen met de Cyrillische letter "Й". We kunnen onszelf gemakkelijk overtuigen dat dit waar is:

public class Main { 

   public static void main(String[] args) throws IOException { 
       char x = 1049; 
       System.out.println(x); 
   } 
} 
Console-uitvoer:

Й
En aangezien forBufferedReader(en in het algemeen BufferedAnythingYouWant) gebufferde klassen worden gebruikt om de prestaties te optimaliseren. Toegang tot een gegevensbron (bestand, console, webresource) is vrij duur in termen van prestaties. Daarom, om het aantal toegangen te verminderen, BufferedReaderleest en verzamelt het gegevens in een speciale buffer, en we halen het vanaf daar. Als gevolg hiervan wordt het aantal keren dat de gegevensbron wordt geopend, verlaagd - mogelijk met meerdere ordes van grootte! Een ander BufferedReaderkenmerk en het voordeel ervan ten opzichte van de gewone InputStreamReader, is de uiterst behulpzame readLine()methode, die hele regels met gegevens leest, geen individuele nummers. Dit is natuurlijk superhandig als het om grote teksten gaat. Zo zien leesregels eruit:

public class Main { 

   public static void main(String[] args) throws IOException { 

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
       String s = reader.readLine(); 
       System.out.println ("The user entered the following text:"); 
       System.out.println(s); 
       reader.close(); 
   } 
}

BufferedReader+InputStreamReader is faster than InputStreamReader alone 
The user entered the following text: 
BufferedReader+InputStreamReader is faster than InputStreamReader alone
Oefenen met het werken met de klassen BuffreredReader en InputStreamReader - 2Is natuurlijk BufferedReaderheel flexibel. U bent niet beperkt tot het werken met het toetsenbord. U kunt bijvoorbeeld gegevens rechtstreeks van internet lezen door simpelweg de vereiste URL aan een lezer door te geven:

public class URLReader { 

   public static void main(String[] args) throws Exception { 

       URL oracle = new URL("https://www.oracle.com/index.html"); 
       BufferedReader in = new BufferedReader( 
               new InputStreamReader(oracle.openStream())); 

       String inputLine; 
       while ((inputLine = in.readLine()) != null) 
           System.out.println(inputLine); 
       in.close(); 
   } 
}
U kunt gegevens uit een bestand lezen door het bestandspad door te geven:

public class Main { 

   public static void main(String[] args) throws Exception { 

       FileInputStream fileInputStream = new FileInputStream("testFile.txt"); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream)); 

       String str; 

       while ((str = reader.readLine()) != null)   { 
           System.out.println (str); 
       } 

       reader.close(); 
   } 
}

System.out vervangen

Laten we nu eens kijken naar een interessante mogelijkheid die we nog niet eerder hebben besproken. Zoals je je zeker herinnert, Systemheeft de klasse twee statische velden - System.inen  System.out. Deze tweelingbroers zijn stroomobjecten. System.inis een InputStream. En System.out is een PrintStream. Op dit moment zullen we het hebben over  System.out. Als we in de Systembroncode van de klasse vallen, zien we dit:

public final class System { 
……………... 
public final static PrintStream out = null; 
 ………… 
} 
Het is dus  System.out  gewoon een gewone statische variabele van deSystem klasse. Er is niets magisch aan :) De outvariabele is een PrintStreamreferentie. Hier is een interessante vraag: wanneer System.out.println()wordt uitgevoerd, waarom gaat de uitvoer precies naar de console en niet ergens anders? En kan dit op de een of andere manier veranderd worden? Stel dat we gegevens van de console willen lezen en naar een tekstbestand willen schrijven. Is het mogelijk om dit op de een of andere manier eenvoudig te implementeren door gebruik te maken van  System.outin plaats van extra lezers- en schrijversklassen? Inderdaad, dat is het :) En we kunnen het doen, ook al System.outis de variabele gemarkeerd met de finalmodifier!  Oefenen met het werken met de klassen BuffreredReader en InputStreamReader - 3Dus wat hebben we nodig om dit voor elkaar te krijgen? Allereerst hebben we een nieuw PrintStreamobject nodig om het huidige te vervangen. Het huidige object, ingesteld in deSystemclass, dient niet onze doeleinden: het verwijst naar de console. U moet een nieuwe maken die verwijst naar een tekstbestand - de "bestemming" voor onze gegevens. Ten tweede moeten we begrijpen hoe we een nieuwe waarde aan de System.outvariabele kunnen toekennen. U kunt geen eenvoudige toewijzingsoperator gebruiken, omdat de variabele is gemarkeerd met final. Laten we vanaf het einde achteruit werken. Toevallig Systemheeft de klasse de methode die we nodig hebben: setOut(). Het neemt een PrintStreamobject en stelt het in als de bestemming voor uitvoer. Dat is precies wat we nodig hebben! Het enige dat overblijft is het creëren van een PrintStreamobject. Dit is ook makkelijk:

PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
De volledige code ziet er als volgt uit:

public class SystemRedirectService { 

   public static void main(String arr[]) throws FileNotFoundException 
   { 
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
       /* Save the current value of System.out in a separate variable so that later 
       we can switch back to console output */ 

       PrintStream console = System.out; 
       // Assign a new value to System.out 
       System.setOut(filePrintStream); 
       System.out.println("This line will be written to the text file"); 

       // Restore the old value of System.out 
       System.setOut(console); 
       System.out.println("But this line will be output to the console!"); 
   } 
}
Het resultaat is dat de eerste string naar het tekstbestand wordt geschreven en de tweede wordt weergegeven in de console :) U kunt deze code naar uw IDE kopiëren en uitvoeren. Open het tekstbestand en je zult zien dat de string daar met succes is geschreven :) Hiermee is onze les tot een einde gekomen. Vandaag herinnerden we ons hoe we met streams en lezers kunnen werken. We herinnerden ons hoe ze van elkaar verschillen en leerden over enkele nieuwe mogelijkheden van System.out, die we in bijna elke les hebben gebruikt :) Tot de volgende lessen!