Interfata Enumeration
Interfata face parte din pachetul j ava . util si este implementata de acele clase care genereaza o enumerare de obiecte. Trebuie implementate urmatoarele 2 metode.
public abstract boolean hasMoreElements(); public abstract Object nextElement() throws NoSuchElementException
Interfata este implementata in clasele: SequencelnputStream, Hashtable, Vector, StringTokenizer
Clasa Vector
Clasa Vector implementeaza un vector de elemente de tip Object.
Atunci cand numarul de elemente introduse intr-un obiect de tip Vector depaseste
capacitatea vectorul este redimensionat automat.
Constructori
Vector() - construieste un vector vid.
Vector(int capacitate) - construieste un vector vid cu capacitatea specificata.
Vector(int capacitate, int increment) - construieste un vector vid cu capacitatea si
incrementul de redimensionare specificate
Metode principale
addElement(Object ob) - adauga la sfarsit insertElementAt(Object ob, int index) setElementAt(Object obnou, int index)
removeAllElements()
removeElement(Object obeliminat) - prima aparitie este eliminata
removeElementAt(int index)
firstElement() lastElement() elementAt(int index)
contains(Object ob) - cauta obiectul ob in vector
indexOf(Object)
lastIndexOf(Object)
clone() - returneaza clona (copia) unui vector
Obs. Clasele care supradefinesc clone() trebuie sa implementeze interfata Cloneable copyInto(Object[]) - copiaza vectorul intr-un tablou
boolean isEmpty()
int size() - intoarce numarul de componente ale vectorului
String toString()
elements() - intoarce o enumerare cu componentele vectorului
Implementandu-se un vector de elemente Object, inserarea elementelor de tipuri de
date primitive necesita « infasurarea »lor in clasele "wrapper" (Integer, Float, Double
etc).
Recuperarea valorilor primitive trebuie facuta utilizand cast si metoda potrivita a
clasei infasuratoare.
Exemplu.
import java.util.*;
public class Casturi {
public static void main(String args[])
{
double a=1.55,b;
Vector xv=new Vector(lO);
xv.addElement(new Double(a));
xv.addElement(Double.valueOf("3.14"));
for(int i=0;i<xv.size();i++) {
b=((Double)xv.elementAt(i)).doubleValue System.out.println("xv["+i+"]="+ b);
Se afiseaza
xv[0]=1.55 xv[l]=3.14
Daca ar fl lipsit cast-ul la extragerea din vector, adica dacaa ar fl fost
b = xv.elementAt(i).doubleValue();
atunci se producea eroarea:
Casturi.Java:13: cannot resolve symbol symbol : method doubleValue () location: class Java.lang.Object
b=xv.elementAt(i).doubleValue();
A
Clasa Vector implementeaza interfata Enumeration, cu ajutorul metodei elements () putem obtine o enumerare. Modul de lucru este urmatorul
Vector v= new Vector(MAX);
// se adauga elemente in v
// V.addElement(x); V.insertElement
Enumeration e = v.elements(); //se obtine enumerarea while(e.hasMoreElements()){
// se prelucreaza obiectul curent returnat de metoda // e.nextElement();
Deoarece nextElement () returneaza o instamta a clasei Ob j ect este necesar un cast.
Clasa Random
Face parte tot din java.util si constituie un generator de numere aleatoare cuprinse intre 0 si 1.
Constructori
Random () creeaza un generator de numere aleatoare initializat functie de
momentul de timp
Random (long seed) creeaza un generator de numere aleatoare initializat
cu seed
Metode
next(int) nextBytesfbvte [])
nextDoubleO - distributie uniforms, in intervalul [0., 1]
nextFloatO - distributie uniforms, in intervalul [0., 1]
nextGaussianO- distributie normala (medie 0 si dispersia 1)
nextlntO- distributie uniforms (sunt produse cu aceeasi probabilitate toate
cele 232 valori posibile de tip int)
nextlntfint n)- distributie uniforms in intervalul [0., n-1] lanseazS
IllegalArgumentException dacS n nu este pozitiv
nextLongQ- distributie uniforma setSeed(long)
Exemplul urmStor integreaza aceste clase.
import java.util.*; class Persoana {
protected String nume; private float kg;
public Persoana(String nume, float kg)
{
this.nume = nume; this.kg=kg;
}
public float g() { return kg;}
class Grupa extends Vector {
String numegrupa;
public Grupa(String ngrp, String[] studenti;
super(30,5);
numegrupa = new String(ngrp);
Random r = new Random();
for(int i=0;i<studenti.length;i
addElement(new Persoana(studenti[i], 50*(l+r.nextFloat() )
public String toString() {
String s= new String("Grupa "+numegrupa+" :");
Enumeration enum_stud= elements (); //super .elements () while (enum_stud.hasMoreElements()) s +=" "+
((Persoana)enum stud.nextElement()).nume; return s;
class Enumerare {
public static void main(String args [ ] ) {
Grupa gr=new Grupa("1131",args);
System.out.println(gr);
// obtinere enumerare din Grupa (deoarece extinde Vector) for(Enumeration eg =gr.elements(); eg.hasMoreElements(); )
{
Persoana studcrt = (Persoana) eg.nextElement();
System.out.println(studcrt.nume+"- "+studcrt.g());
Observatii
1. In clasa Persoana, pentru a da
un exemplu, variabila nume este protected.
Varianta recomandata de implementare a TDA
impune ca variabilele sa fie
private. Atunci pentru a afla valoarea unei astfel
de variabile, kg de
exemplu, este nevoie de o metoda public.
protected String nume; private float kg; // ...
public float g() { return kg;}
2. Clasa Grupa mosteneste clasa Vector, iar prin
s up e r(3 0,5) ;
se apeleaza constructorul Vector(30,5) (trebuie pus in prima pozitie)
3. Utilizarea obiectului Random si a metodei addElement () a clasei Vector
Random r = new Random();
for(int i=0;i<studenti.length;i++)
addElement(new Persoana(studenti[i],
50*(1+r.nextFloat()) ) ) ;
Nu este necesar super . addElement ()
4. Declararea enumerarii nu necesita super inainte de elements()
Enumeration enum stud= elements();
5 . Cand se parcurge enumerarea cast-ul este obligatoriu
while (enum_stud.hasMoreElements()) s +=" "+
((Persoana)enum_stud.nextElement()).nume;
6. In clasa Enumerare, in functia main() se creeaza un obiect de tip Grupa cu nume preluate din linia de comanda
Grupa gr=new Grupa("1131",args); System.out.println(gr);
Aflsarea este produsa pe baza conversiei realizata de redeflnirea metodei toStringO din Grupa, care utilizeaza enumerarea aplicata vectorului.
7. Deoarece Grupa extinde clasa Vector se poate crea o enumerare asociata obiectului
for(Enumeration eg =gr.elements(); eg.hasMoreElements(); ){ Persoana studcrt = (Persoana) eg.nextElement(); System.out.println(studcrt.nume+"- "+studcrt.g()); } Iarasi cast-ul (Persoana) este obligatoriu, lipsa lui producand o eroare de compilare.
Iesirea produsa de comanda
Java Enumerare Costel Marin Sorin Zaharia este urmatoarea
Grupa 1 |
131 |
: Costel Marin Sorin Zaharia |
Costel- |
78 |
.33454 |
Marin- |
77. |
23522 |
Sorin- |
72. |
72203 |
Zaharia- 64.77125 |
Clasa StringTokenizer
Face parte din pachetul java.util si descompune un sir in atomi lexicali (tokeni). Clasa
StringTokenizer implementeaza interfata Enumeration .
public class StringTokenizer implements Enumeration
Constructori
StringTokenizer (String text) - construieste un tokenizer pentru sirul text; delimitatori sunt spatiile albe
StringTokenizer(String text, String delimitatori) StringTokenizer(String text, String delimitatori, boolean intoarceSiDelim) - daca argumentul intoarceSiDelim este true atunci se returneaza si separatorii ca siruri de lungime 1
Metode
public boolean hasMoreTokens() public String nextToken()
public String nextToken(String delim)
Throws: NoSuchElementException public int countTokens()
Mai exista si atomizarea orientata pe elemente de tip Object cu metodele
interfetei Enumeration
public boolean hasMoreElements()
public Object nextElement()
Throws: NoSuchElementException
Exemplu
import java.util.*;
class ExToken {
public static void main(String args [ ] )
{
String text= new String(
"Grupa gr = new Grupa(\"1131\",args);" ) ;
StringTokenizer st = new StringTokenizer(text); while (st.hasMoreElements()) {
System.out.printIn(st.nextElement());
Programul produce urmatoarea iesire
In loc de metodele interfetei
Enumeration se puteau utiliza metodele specifice clasei
StringTokenizer:
StringTokenizer st = new StringTokenizer(text); while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
In continuare se dau diverse exemple de utilizare a constructorului StringTokenizer si rezultatele prelucrarilor corespunzatoare cu programul de mai sus pentru sirul Grupa gr = new Grupa ( "1131", args) ;.
StringTokenizer st = new StringTokenizer(text,"(),");
Grupa gr = new Grupa
"1131"
args
StringTokenizer st = new StringTokenizer(text,"(), \n\r\t");
Grupa gr
new Grupa "1131" args
S-a considerat ca si spatiile albe
sunt delimitatori.
StringTokenizer st = new StringTokenizer(text,"(), \n\r\t",true)
Grupa |
|
|
4--- spatiu |
gr |
|
|
4--- spatiu |
|
4--- spatiu |
new |
|
|
4--- spatiu |
Grupa ( |
|
S-au inclus si delimitatorii ca
atomi (tokens) in rezultat.
Intrari / Ie§iri
Bibliotecile Java utilizeaza o abstractizare uniflcatoare pentru surse diferite de date -
flux (stream).
Cele mai importante tipuri de fluxuri sunt urmatoarele
•
fisier
•
tablou de octeti, caractere
•
obiect String
•
conducts (pipe) care asigura transferul de date de la un capat la altul
(de exemplu
conexiuni Internet)
Fluxuri standard
Operatiile de intrare/ iesire cu terminalul. Aceste fluxuri sunt in permanenta deschise. System.in - intrarea standard (tastatura) System.out - fluxul standard de iesire System.err - fluxul standard de erori
Clase
Clasele care permit efectuarea operatiilor de I/E se pot clasifica in doua categorii
1.
intrari - care extind in principal clasele abstracte Reader si
InputStream, au
toate operatia read()
2.
iesiri - toate care deriva din clasele abstracte Writer si OutputStream
au
operatii de baza
write()
In Java functiile care implementeaza operatiile de I/E se gasesc in pachetul java.io.
Intrari
Una din clasele abstracte importante este clasa Reader. Clasele derivate din acestea sunt urmatoarele
•
InputStreamReader - face
legatura dintre fluxurile orientate pe octeti cu
fluxurile orientate
pe caractere prin transformarea octetilor in caractere (o clasa
derivata este File
Reader care citeste fisiere de tip caracter)
•
FilterReader - clasa abstracts pentru fluxurile de tip caracter
•
CharArrayReader - datele sunt preluate dintr-un tablou de caractere
•
StringReader - datele sunt preluate dintr-un sir
•
PipedReader-fluxurile de tip pipe orientate caracter
•
Buf feredReader - intrari de tip text din fluxuri caracter
Ultima clasa este o clasa infasuratoare pentru intrari buffer-izate care permite
utilizarea optima a celorlalte fluxuri.
Metoda caracteristica clasei Buf feredReader este readLine:
public String readLine() throws IOException
care citeste o linie delimitate fie de '\n', fie de '\r', de secventa "\r\n".
Metoda returneaza linia citita sub forma unui obiect String continand toate
caracterele cu exceptia delimitatorului de linie. Atunci cand s-a detectat EOF
metoda returneaza null.
Dimensiunea buffer-ului utilizat acopera nevoile de eficienta ale multor aplicatii. Se recomanda ca celelate fluxuri sa fie infasurate in Buf f eredReader
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
BufferedReader fis = new BufferedReader(new FileReader("date.in")); BufferedReader f car = new BufferedReader(
new CharArrayReader(tablou_caractere)); BufferedReader f_sir = new BufferedReader(
new StringReader(obiectString));
Exemplu. S-au evidentiat neajunsurile de portabilitate Unix - Windows pentru metodele statice ale clasei citeste care utiliza fluxul standard de intrare. In continuare este propusa clasa CitesteFlux care permite accesul la trei tipuri de surse de date, potrivit constructorului utilizat
1.
intrarea standard
2.
fisier de caractere
3.
tablou de caractere din memorie
Desigur si aceasta clasa poate fi generalizata pentru toate tipurile de fluxuri acceptate in Java. Aici s-a considerat doar o transformare a clasei citeste, cu valoare de exemplu, doar în cazurile celor trei tipuri de fluxuri amintite.
Datorita faptului ca metoda readLine() filtreaza '\n' si '\r' metodele ei sunt portabile.
package citeste; import java.io.*;
public class CitesteFlux {
//
BufferedReader in;
boolean stdin=false, close=false;
Reader fr=null;
public CitesteFlux(){
in=new BufferedReader(
new InputStreamReader (System.in)
) ;
stdin=true; }
public CitesteFlux (String numef){ try{
in=new BufferedReader(
fr=new FileReader (numef)
) ; } catch (FileNotFoundException e) {
System.out.println("Fisierul "+ numef+" nu poate fi deschis
public CitesteFlux(char x[]){ in=new BufferedReader(
fr=new CharArrayReader (x)
public char car(String text) {
char c;
if(text!="") System.out.print(text);
try {
c=(char)System.in.read();
// se ignora Carriage Return
if (c=='\r') c=(char)System.in.read
} catch(IOException e) {return '\n';}
return c;
public String sir(String text) { String s=null;
if(stdin && text!="") System.out.print(text); try {
s=in.readLine(); // null daca sfarsit de stream } catch(IOException e) {
System.out.print("Eroare de I/E"); } return s==null?"":s;
public int intreg(String text)
{
boolean repeta; String scitit=""; do {
repeta=false; try {
return Integer.parselnt(scitit=sir(text)
} catch(NumberFormatException e){ if(stdin) repeta=true;
else System.out.print("Fluxul "+fr); System.out.println(" - nr. intreg incorect:"+scitit)
}
} while(repeta); return 0;
public double real (String text) {
boolean repeta; String scitit; do {
repeta=false,• scitit=sir(text); try {
return Double.parseDouble(scitit); } catch(NumberFormatException e){ if(stdin) repeta=true;
else System.out.print("Fluxul "+fr); System.out.println(" - nr. real incorect }
} while(repeta); return 0.;
public void close() {
if ( !stdin)
if (close) System.out.println("Flux deja inchis " + fr) ; else try {
in.close () ; close=true; } catch(IOException e) { }
public void finalize {
close () ;
Se observa ca metodele intreg(text) si real(text) reiau introducerea datelor doar in
cazul fluxului standard de intrare, dar eroarea este afisata totdeauna (denumirea
fluxului este afisata doar daca nu este vorba de fluxul standard de intrare).
În cazul erorilor detectate în fluxuri "nestandard" se returneaza 0.
Pentru afisarea fluxului in care s-a produs o eroare de conversie s-a utilizat variabila
Reader fr=null; care este initializata de fiecare constructor
in=new BufferedReader(
fr=new FileReader (numef)
Daca s-a construit un obiect
CitesteFlux pe baza fluxului standard de intrare atunci variabila booleana stdin are valoarea
true.
Inchiderea fluxului este posibila prin apelarea explicits a metodei close () fie implicit, la eliberarea spatiului ramas disponibil (prin redefinirea metodei
finalize () a clasei Object).
Testarea acestei clase a fost efectuata cu programul urmator
import citeste.*; class Ex_CitesteFlux {
public static void main(String args [ ] )
{
String linia="";
for(int i=0,l=0; i<args.length;i++)
linia= linia.concat(args[i]+"\n");
CitesteFlux flux[]= new CitesteFlux[]{
new CitesteFlux("num.dat"),
new CitesteFlux(linia.toCharArray()),
new CitesteFlux()
int n;
double x;
for(int i=0; i<flux.length;
n=flux[i].intreg("n (intreg)="); x=flux[i].real("x (real)=");
System.out.println("S-a citit din fluxul:"+i+" n,x,sir=" , "+ x + " si "+flux[i].sir("Sir="));
flux[O].close();
flux[O].close(); // va genera mesajul flux deja inchis
Continutul fisierului num.dat
19
3 .141527
abcdefgh
Daca programul este lansat cu comanda
Java Ex_CitesteFlux fara argumente in linia de comanda, rezultatul este urmatorul
S-a citit din fluxul:0 n,x,sir=19 , 3.141527 si abcdefgh
Fluxul java.io.CharArrayReader@7c6768 - nr. intreg
incorect:
Fluxul java.io.CharArrayReader@7c6768 - nr. real
incorect:
S-a citit din fluxul:1 n,x,sir=0 , 0.0 si
n (intreg)=12345678
x (real)=2e.2
- nr. real incorect:2e.2 x (real)=2.e2
|
|
|
|
|
|
|
|
S-a citit |
din fluxul |
:2 |
n,x,sir=12345678 |
, 2 |
00. |
0 |
si Stop |
Flux deja |
inchis |
|
|
|
|
|
|
In fluxul 1, new CitesteFlux (linia. toCharArray () ), deoarece linia a fost Un
sir vid nu s-au putut citi cele trei valori cu metodele intreg(), real(), sir(). Un mesaj de eroare a fost produs pentru fiecare citire a unei valori numerice si s-au returnat valori implicite.
O alta executie a acestui program este urmatoarea:
c:\pg\sd\Curs4>java Ex |
CitesteFlux |
2003 1.000001 LINIE |
||
S-a citit din fluxul:0 |
n, |
x,sir=19 , |
3.141527 si abcdefgh |
|
S-a citit din fluxul:1 |
n, |
x,sir=2003 |
, 1.000001 |
si LINIE |
n (intreg)=+l |
|
|
|
|
- nr. intreg incorect: |
+ 1 |
|
|
|
n (intreg)=0000001 |
|
|
|
|
x (real)=6.026+e23 |
|
|
|
|
- nr. real incorect:6. |
02 |
6+e23 |
|
|
x (real)=6.026e+23 |
|
|
|
|
Sir=gata |
|
|
|
|
S-a citit din fluxul:2 |
n, |
x,sir=l , |
6.026E23 si |
gata |
Flux deja inchis |
|
|
|
|
Un dezavantaj al clasei CitesteFlux este faptul ca fiecare element citit trebuie sa se termine cu LINE FEED (x \n') sau CARRIAGE RETURN (x\r'). Pentru a putea citi si campuri separate de spatii se va defini o alta clasa, CitesteFluxCampuri, care descompune linia in campuri cu ajutorul clasei S tringTokenizer.
package citeste; import java.io.*; import Java.util.*;
public class CitesteFluxCampuri extends CitesteFlux{
StringTokenizer st= new StringTokenizer("");
I/-------------------------------------------------------------------------------------------------------------------
public CitesteFluxCampuri(){
super(); } public CitesteFluxCampuri (String numef){
super(numef);
}
public CitesteFluxCampuri(char x[]){ super(x);
public String sir(String text) {
if(st.hasMoreTokens()) return st.nextToken
String s=null;
s=super.sir(text);
st= new StringTokenizer(s==null?"":s);
if(st.hasMoreTokens()) return st.nextToken else return "";
public String Linie(String text) {
// elimina toate elementele din st if(st.hasMoreTokens())
while(st.hasMoreTokens()) st.nextToken() // citeste o linie noua return super.sir(text);
Observatii
1.
In clasa CitesteFluxCampuri s-a redefinit metoda sir() a clasei de baza
astfel
incat sa fie returnat ca sir campul curent. Daca este necesar citirea unei
linii,
un sir care se termina
cu '\n' sau '\r' sau cu secventa "\r\n", s-a scris o
noua metoda Linie(text).
2.
Metoda Linie (text) are ca efect ignorarea tuturor campurilor de pe
linia
curenta si citirea
unei linii noi. Scrieti o alta versiune care sa returneze la apel
ceea ce a ramas de pe
linia curenta si doar an cazul ca au fost epuizati toti
atomii sa citeasca o
noua linie.
3.
Metodel intreg() si real() nu au fost redefinite in CitesteFluxCampuri.
Atunci
când un obiect de
acest tip le va apela, vor fi executate metodele respective din
CitesteFlux, insa
apelurile sir() din corpul lor vor fi directionate catre metoda
sir() redefinita in
clasa derivata.
Programul de test nu difera mult de eel precedent. S-a format din argumente un sir in care ultimul argument este separat de celelalte printr-un "\n".
import citeste.*;
class Ex CitesteFluxCampuri {
public static void main(String args [ ] ) {
String linia="";
for(int i=0,l=0; i<args.length;i++)
linia=linia.concat(args[i] +(i==args.length-2?"\n":" "));
CitesteFluxCampuri flux[]= new CitesteFluxCampuri[]{
new CitesteFluxCampuri("linii.dat"), new CitesteFluxCampuri(linia.toCharArray()), new CitesteFluxCampuri() };
int n; double x; for(int i=0; i<flux.length;i++) {
n=flux[i].intreg("n (intreg)="); x=flux[i].real("x (real)=");
System.out.println("S-a citit din fluxul:"+i+"
n,x,sir=" +n+" , "+ x + " si "+flux[i].Linie("Sir="));
flux [0] .close (); flux [0] .close ();
Continutul fisierului linii . dat
19 3.141527 abcdefgh Noul sir de pe linie noua
Rezultatul unei executii
c:\pg\sd\Curs4>java Ex_CitesteFluxCampuri
2003 1.000001 Camplgnorat LINIE
S-a citit din fluxul:0 n,x,sir=19 , 3.141527 si Noul sir
de pe linie noua
S-a citit din fluxul:l n,x,sir=2003 , 1.000001 si LINIE
n (intreg)=1
x (real)=-2.5
Sir=aaa bbb ccc ddd
S-a citit din fluxul:2 n,x,sir=l , -2.5 si aaa bbb ccc
ddd
Flux deja inchis
O clasa abstracts dedicata iesirilor este clasa anstracta Writer. Subclasele din pachetul java.io implementeaza operatiile de scriere in fluxurile cunoscute (standard, fisier,memorie, tip pipe) corespunzatoare subclaselor clasei abstracte< Reader.
BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter
PrintWriter
Este o clasa ce permite iesiri in fluxuri de tip text. Daca este activata optiunea de flush automat, atunci ori de cate ori se executa println() se va executa si flush. PrintWriter nu lanseaza excep-ii de aceea rezultatul operatiei trebuie verificat cu checkError().
Din considerente de eficienta este necesara utilizarea clasei infasuratoare
BufferedWriter camaijos.
PrintWriter ies
= new PrintWriter(new BufferedWriter(new FileWriter("rez.dat")
Constructori
PrintWriter(OutputStream out)
Construieste un nou obiect PrintWriter, fara flush automat de linii., pe baza unui obiect existent deja de tip OutputStream.
PrintWriter(OutputStream out, boolean autoFlush)
Construieste un nou obiect PrintWriter pe baza unui obiect existent deja de tip OutputStream.
PrintWriter(Writer out)
Construieste un nou obiect PrintWriter, fara flush automat de linii.
PrintWriter(Writer out, boolean autoFlush)
Construieste un nou obiect PrintWriter. Metode importante
boolean checkError () - flush linia curenta si veriflca daca a fost eroare
void print(boolean b) void print(char c) void print(char[] s) void print(double d) void print(float f) void print(int i) void print(long 1) void print(Object obj) void print(String s)
void printin () - termina linia curenta scriind un separator de linie
void printin(boolean x) void printin(char x) void printin(char[] x) void printin(double x) void printin(float x) void printin(int x) void printin(long x) void printin(Object x) void printin(String x)
Exemplu de utilizare (din Bruce Eckel, Thinking in Java)
import java.io.*;
public class IOStreamDemo {
// Throw exceptions to console: public static void main(String[] args) throws IOException {
// 1. Reading input by lines: BufferedReader in = new BufferedReader(
new FileReader("IOStreamDemo.Java")); String s, s2 = new String();
while((s = in.readLine())!= null)
s2 += s + "\n"; in.close();
// lb. Reading standard input: BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in)); System.out.print("Enter a line:"); System.out.println(stdin.readLine());
// 2. Input from memory
StringReader in2 = new StringReader(s2); int c;
while((c = in2.read()) != -1) System.out.print((char)c);
// 3. Formatted memory input try {
DatalnputStream in3 = new DatalnputStream(
new ByteArraylnputStream(s2.getBytes(; while(true)
System.out.print((char)in3.readByte()); } catch(EOFException e) {
System.err.println("End of stream");
// 4. File output try {
BufferedReader in4 = new BufferedReader(
new FileReader(s2)); PrintWriter outl = new PrintWriter(
new BufferedWriter(
new FileWriter("IODemo.out"))); int lineCount = 1; while((s = in4.readLine()) != null )
outl.println(lineCount++ + ": " + s); outl.close(); } catch(EOFException e) {
System.err.println("End of stream");
Transformarea System.out în PrinterWriter
import java.io.*;
public class SchimbaSystemOut {
public static void main(String[] args) PrintWriter out =
new PrintWriter(System.out, true); out.println("Salut !");