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


Sir=Stop

 

 

 

 

 

 

 

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