Bună! Astăzi vom vorbi despre clasa Java PrintStream și tot ce poate face. De fapt, ești deja familiarizat cu două metode ale clasei PrintStream . Sunt print() și println() , pe care probabil le folosiți în fiecare zi :) Deoarece variabila System.out este un obiect PrintStream , apelați una dintre metodele acestei clase atunci când apelați System.out.println() .  Scopul general al clasei PrintStream este de a trimite informații către un flux. De ce avem nevoie de clasa PrintStream - 1Această clasă are mai mulți constructori. Iată câteva dintre cele mai frecvent utilizate:
  • PrintStream(OutputStream outputStream)
  • PrintStream(File outputFile) aruncă FileNotFoundException
  • PrintStream(String outputFileName) aruncă FileNotFoundException
De exemplu, putem trece numele fișierului de ieșire constructorului PrintStream . Alternativ, putem trece un obiect File . Să ne uităm la câteva exemple pentru a vedea cum funcționează:

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); 

   } 
}
Acest cod va crea un fișier test.txt pe desktop (dacă nu există deja) și va scrie succesiv numărul, șirul și booleanul nostru. Iată conținutul fișierului după ce rulăm programul:

222 
Hello world!
false
După cum am spus mai sus, nu trebuie să treceți un obiect File . Este suficient să treceți pur și simplu calea fișierului către 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); 
   } 
}
Acest cod face la fel ca codul anterior. O altă metodă interesantă care merită atenția noastră este printf() , care produce rezultate bazate pe un șir de format. Ce este un „șir de format”? Să dau un exemplu:

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(); 
   } 
}
Aici, în loc să menționăm în mod explicit numele și vârsta robotului nostru în șir, punem substituenți pentru aceste informații, reprezentați de %s și %d . Și trecem drept argumente datele care le vor înlocui. În cazul nostru, acesta este șirul „ Amigo ” și numărul 18. Am putea crea un alt substituent, să spunem %b și să trecem un alt argument. De ce avem nevoie de asta? Mai presus de toate, pentru o mai mare flexibilitate. Dacă programul dvs. cere să afișați des un mesaj de bun venit, va trebui să introduceți manual textul necesar pentru fiecare robot nou. Nici măcar nu poți face din acest text o constantă, deoarece fiecare are nume și vârste diferite! Dar folosind această nouă metodă, puteți izola salutul într-o constantă și, dacă este necesar, pur și simplu schimbați argumentele transmise metodei printf() .

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(); 
   } 
} 

Înlocuirea System.in

În această lecție, vom „lupta cu sistemul” și vom învăța cum să înlocuim variabila System.in pentru a redirecționa ieșirea sistemului către oriunde dorim. S-ar putea să uiți ce este System.in , dar niciun student CodeGym nu va uita vreodată acest construct:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in  (la fel ca System.out ) este o variabilă statică a clasei System . Dar, spre deosebire de System.out , face referire la o altă clasă, și anume InputStream . În mod implicit, System.in este un flux care citește date de pe un dispozitiv de sistem - tastatura. Cu toate acestea, la fel ca și în cazul System.out , putem înlocui tastatura ca sursă de date. Putem citi datele de oriunde vrem! Să ne uităm la un exemplu:

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); 
       } 

   } 
}
Deci ce am făcut? System.in este de obicei legat de tastatură. Dar nu vrem să citim date de la tastatură: să facem ca datele să fie citite dintr-un șir obișnuit! Am creat un șir și l-am obținut ca o matrice de octeți. De ce avem nevoie de octeți? Chestia este că InputStream este o clasă abstractă, așa că nu putem crea o instanță a acesteia direct. Trebuie să alegem unul dintre descendenții săi. De exemplu, putem alege ByteArrayInputStream . Este simplu și doar numele său ne spune cum funcționează: sursa de date este o matrice de octeți. Deci creăm o matrice de octeți și o transmitem constructorului fluxului nostru care va citi datele. Și acum totul este gata! Acum trebuie doar să folosim System.setIn()metodă pentru a seta în mod explicit valoarea variabilei in . Cu out , vă veți aminti, nici nu a fost posibilă setarea directă a valorii variabilei: a trebuit să folosim metoda setOut() . După ce ne atribuim InputStream variabilei System.in , vrem să verificăm dacă ne-am atins scopul. Vechiul nostru prieten BufferedReader ne vine în ajutor aici. În mod normal, acest cod ar fi deschis consola în IntelliJ IDEA și apoi ar fi citit datele pe care le-ați introdus de la tastatură.

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

       String str; 

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

           System.out.println(str); 
       }
Dar acum, când îl rulați, veți vedea că șirul nostru este pur și simplu afișat în consolă. Nu se citește de la tastatură. Am înlocuit sursa de date. Nu mai este tastatura, ci șirul nostru! Este atât de simplu :) În lecția de astăzi, am cunoscut o nouă clasă și am explorat un mic hack nou pentru lucrul cu I/O. Acum este timpul să ne întoarcem la curs și să finalizați câteva sarcini :) Ne vedem la următoarea lecție!