Hoi! Vandaag zullen we het hebben over de Java PrintStream-klasse en alles wat deze kan doen. U bent eigenlijk al bekend met twee methoden van de klasse PrintStream . Dit zijn print() en println() , die u waarschijnlijk elke dag gebruikt :) Omdat de variabele System.out een PrintStream- object is, roept u een van de methoden van deze klasse aan wanneer u System.out.println() aanroept .  Het algemene doel van de klasse PrintStream is om informatie naar een bepaalde stroom te sturen. Waarom we de PrintStream-klasse nodig hebben - 1Deze klasse heeft verschillende constructors. Hier zijn enkele van de meest gebruikte:
  • PrintStream(UitvoerStream uitvoerStream)
  • PrintStream (File outputFile) genereert FileNotFoundException
  • PrintStream(String outputFileName) genereert FileNotFoundException
We kunnen bijvoorbeeld de naam van het uitvoerbestand doorgeven aan de PrintStream- constructor. Als alternatief kunnen we een File- object doorgeven. Laten we enkele voorbeelden bekijken om te zien hoe dit werkt:

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.PrintStream; 

public class Main { 

   public static void main(String arr[]) throws FileNotFoundException 
   { 
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt")); 

       filePrintStream.println(222); 
       filePrintStream.println("Hello world"); 
       filePrintStream.println(false); 

   } 
}
Deze code maakt een test.txt-bestand op het bureaublad (als het nog niet bestaat) en schrijft er achtereenvolgens ons nummer, de string en de boolean naar toe. Dit is de inhoud van het bestand nadat we het programma hebben uitgevoerd:

222 
Hello world!
false
Zoals we hierboven zeiden, hoeft u geen File- object door te geven. Het volstaat om gewoon het bestandspad door te geven aan de constructor:

import java.io.FileNotFoundException; 
import java.io.PrintStream; 

public class Main { 

   public static void main(String arr[]) throws FileNotFoundException 
   { 
       PrintStream filePrintStream = new PrintStream("C:\\Users\\Username\\Desktop\\test.txt"); 

       filePrintStream.println(222); 
       filePrintStream.println("Hello world"); 
       filePrintStream.println(false); 
   } 
}
Deze code doet hetzelfde als de vorige code. Een andere interessante methode die onze aandacht waard is, is printf() , die uitvoer produceert op basis van een formaatstring. Wat is een "format string"? Laat me een voorbeeld geven:

import java.io.IOException; 
import java.io.PrintStream; 

public class Main { 

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

       PrintStream printStream = new PrintStream("C:\\Users\\Steve\\Desktop\\test.txt");

       printStream.println("Hello!"); 
       printStream.println("I'm a robot!"); 

       printStream.printf("My name is %s. I am %d!", "Amigo", 18); 

       printStream.close(); 
   } 
}
In plaats van expliciet de naam en leeftijd van onze robot in de tekenreeks te vermelden, plaatsen we hier tijdelijke aanduidingen voor deze informatie, vertegenwoordigd door %s en %d . En we geven als argumenten de gegevens door die ze zullen vervangen. In ons geval is dit de tekenreeks " Amigo " en het getal 18. We kunnen een andere tijdelijke aanduiding maken, bijvoorbeeld %b , en een ander argument doorgeven. Waarom hebben we dit nodig? Vooral voor meer flexibiliteit. Als uw programma vereist dat u vaak een welkomstbericht weergeeft, moet u de benodigde tekst voor elke nieuwe robot handmatig typen. Je kunt deze tekst niet eens een constante maken, aangezien iedereen verschillende namen en leeftijden heeft! Maar met deze nieuwe methode kunt u de begroeting in een constante isoleren en, indien nodig, eenvoudigweg de argumenten wijzigen die aan de methode printf() zijn doorgegeven .

import java.io.IOException; 
import java.io.PrintStream; 

public class Main { 

   private static final String GREETINGS_MESSAGE = "My name is %s. I am %d!"; 

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

       PrintStream printStream = new PrintStream("C:\\Users\\Steve\\Desktop\\test.txt"); 

       printStream.println("Hello!"); 
       printStream.println("We are robots!"); 


       printStream.printf(GREETINGS_MESSAGE, "Amigo", 18); 
       printStream.printf(GREETINGS_MESSAGE, "R2-D2", 35); 
       printStream.printf(GREETINGS_MESSAGE, "C-3PO", 35); 

       printStream.close(); 
   } 
} 

System.in vervangen

In deze les gaan we "het systeem bevechten" en leren we hoe we de variabele System.in kunnen vervangen om systeemuitvoer om te leiden naar waar we maar willen. Je zou kunnen vergeten wat System.in is, maar geen enkele CodeGym-student zal deze constructie ooit vergeten:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in  (net als System.out ) is een statische variabele van de klasse System . Maar in tegenstelling tot System.out verwijst het naar een andere klasse, namelijk InputStream . System.in is standaard een stream die gegevens leest van een systeemapparaat: het toetsenbord. Net als bij System.out kunnen we echter het toetsenbord als gegevensbron vervangen. We kunnen gegevens lezen van waar we maar willen! Laten we naar een voorbeeld kijken:

import java.io.*; 

public class Main { 

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

       String greetings = "Hi! My name is Amigo!\nI'm learning Java on the CodeGym website.\nOne day I will become a cool programmer!\n"; 
       byte[] bytes = greetings.getBytes(); 

       InputStream inputStream = new ByteArrayInputStream(bytes); 

       System.setIn(inputStream); 

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 

       String str; 

       while ((str = reader.readLine())!= null) { 

           System.out.println(str); 
       } 

   } 
}
Dus wat hebben we gedaan? System.in is meestal gebonden aan het toetsenbord. Maar we willen geen gegevens van het toetsenbord lezen: laten we de gegevens uit een gewone string laten lezen! We hebben een string gemaakt en deze als een byte-array gekregen. Waarom hebben we bytes nodig? Het punt is dat InputStream een ​​abstracte klasse is, dus we kunnen er niet rechtstreeks een instantie van maken. We moeten een van zijn nakomelingen kiezen. We kunnen bijvoorbeeld ByteArrayInputStream kiezen . Het is eenvoudig en alleen al de naam vertelt ons hoe het werkt: de gegevensbron is een byte-array. Dus we maken een byte-array en geven deze door aan de constructor van onze stream die de gegevens zal lezen. En nu is alles klaar! Nu hoeven we alleen nog maar de System.setIn() te gebruikenmethode om expliciet de waarde van de variabele in in te stellen . Zoals u zich herinnert, was het met out ook niet mogelijk om de waarde van de variabele rechtstreeks in te stellen: we moesten de methode setOut() gebruiken . Nadat we onze InputStream aan de variabele System.in hebben toegewezen , willen we controleren of we ons doel hebben bereikt. Onze oude vriend BufferedReader komt ons hier te hulp. Normaal gesproken zou deze code de console in IntelliJ IDEA hebben geopend en vervolgens de gegevens lezen die u via het toetsenbord hebt ingevoerd.

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 

       String str; 

       while ((str = reader.readLine())!= null) { 

           System.out.println(str); 
       }
Maar als je het nu uitvoert, zul je zien dat onze string eenvoudig wordt weergegeven in de console. Er wordt niet van het toetsenbord gelezen. We hebben de gegevensbron vervangen. Het is niet langer het toetsenbord, maar onze snaar! Zo simpel is het :) In de les van vandaag leerden we een nieuwe klas kennen en verkenden we een kleine nieuwe hack voor het werken met I/O. Nu is het tijd om terug te keren naar de cursus en wat taken uit te voeren :) Tot ziens in de volgende les!