I/O elementare
Java
IO elementare
Prof. Francesco Bellotti
ELIOS Lab - DIBE – The University of Genoa
1
Il package java.io
Il linguaggio Java non ha istruzioni
(statement) standard per fare l’input e output
I/O fatto attraverso metodi (funzioni) che sono
parte di un package
Un package è una collezioni di classi che
offrono funzionalità usabili da altri programmi
Un package è come una scatola degli attrezzi con
le classi che sono gli attrezzi
Per fare l’I/O di base usiamo il package
java.io, che è il più semplice
Ne esistono anche altri più specialistici
2
I/O streams
In Java, una sorgente di dati di input è detta un input stream e i
dati in uscita sono detti output stream
In generale, un programma può avere più stream di input e di
output
Per iniziare, ueseremo 3 semplici stream di IO
System.in — lo stream di input
System.out — lo stream di output normale
System.err — lo stream di output per i messaggi di errore
System.in è tipicamente collegato alla tastiera e i dati sono
caratteri
System.out e System.err sono collegati al monitor e i dati sono
sempre caratteri
3
Input e output
4
Input & output stream
5
Esempio di IO
import java.io.*;
class Echo
{
public static void main (String[] args) throws IOException
{
//Analizzeremo in seguito queste 2 linee.
//Per ora consideriamole necessarie per creare
//l’oggetto stdin usato per leggere da tastiera
InputStreamReader inStream = new InputStreamReader( System.in ) ;
BufferedReader stdin = new BufferedReader( inStream );
String inData;
C:\users\default>java Echo
Enter the data:
System.out.println("Enter the data:");
//legge una riga di codice dalla tastiera
inData = stdin.readLine();
System.out.println("You entered:" + inData );
This is what the user enters
You entered:This is what the user
enters
C:\users\default>
}
}
6
Analizzando il programma
import java.io.*;
avverte il compilatore di usare il package java.io
 Il simbolo * significa che ogni classe di quel package potrebbe
essere usata
throws IOException
E’necessaria per programmi che fanno input (almeno per
ora)
Informa il compilatore che il metodo main() potrebbe fallire
 Se main() dovesse fallire, la Java Virtual Machine che
interpreta il programma Java gestirà una “accettabile” chiusura
del programma
Le eccezioni (situazioni di possibile errore) o vengono
gestite localmente in un metodo, oppure vengono rilanciate
dal metodo ad altri metodi (i metodi chimanti) o alla virtual
machine (come appunto in questo caso)
7
Creazione dell’oggetto per leggere da tastiera
La variabile inStream è usata solo per
connettere l’InputStreamReader al
BufferedReader
InputStreamReader inStream = new
InputStreamReader( System.in ) ;
BufferedReader stdin = new BufferedReader(
inStream );
Si può semplificare il codice scrivendo una
sola riga
BufferedReader stdin = new BufferedReader(new
InputStreamReader(System.in));
8
Convertire stringhe di caratteri in valori numerici
Usando il programma Echo, se si
inseriscono da tastiera dei valori
numerici, questi sono letti come
caratteri
Verificalo!
E se voglio leggere dei numeri?
Devo trasformare i caratteri in numeri
Usando i metodi della classe Integer, che è il
wrapper del tipo int
9
Lettura di valori numerici
import java.io.*;
class EchoSquare
{
public static void main (String[] args) throws IOException
{
BufferedReader stdin =
new BufferedReader (new InputStreamReader(System.in));
String inData;
int num, square;
// declare two int variables
System.out.println("Enter an integer:");
inData = stdin.readLine();
num = Integer.parseInt( inData ); // convert inData to int
square = num * num ;
// compute the square
System.out.println("The square of " + inData + " is " + square);
}
}
10
Convertire stringhe di caratteri in valori numerici
Ovviamente, si può anche scrivere il valore
direttamente nell’argomento
num = Integer.parseInt( "39" );
E se l’utente del programma scrivesse un intero in
formato sbagliato?
134 -45
 Sono ok
1 4 9 2 14.92 centotrentquattro
“ 134”
 Sono sbagliati
Lo statement inData = stdin.readLine() non darebbe
alcun problema
Ma num = Integer.parseInt( inData ) non sarebbe in
grado di interpretare la sequenza come un intero
Il metodo parseInt() lancia un’eccezione di tipo
NumberFormatException
Enter an integer:
14.92
java.lang.NumberFormatException: 14.92
11
Esempio: somma di 2 interi
import java.io.*;
class AddTwo
{
public static void main (String[] args) throws IOException
{
BufferedReader stdin =
new BufferedReader ( new InputStreamReader( System.in ) );
String line1, line2;
int first, second, sum ;
// declaration of input Strings
// declaration of int variables
System.out.println("Enter first integer:");
line1 = stdin.readLine();
first = Integer.parseInt( line1 );
// convert line1 to first int
System.out.println("Enter second integer:");
line2 = stdin.readLine();
second = Integer.parseInt( line2 );
// convert line2 to second int
sum
= first + second;
// add the two ints, put result in sum
System.out.println("The sum of " +
first + " plus " + second +" is " + sum );
}
}
12
Esercizi di programmazione
Riscrivi il programma in modo che
poduca lo stesso output, ma senza
usare nel println finale né la variabile
first né la variabile second
Scrivere un programma simile al
precedente, che riceva dall’utente i
valori di un dividendo e di un divisore
interi e produca in output i risultati della
divisione e del resto
13
Esercizi di programmazione
Scrivere un programma che legga un
numero di centesimi e scriva il numero
di Euro e centesimi
D:\users\default>java Dollars
Inserisci il numero di centesimi: 324
Sono 3 euro e 24 centesimi
Usa aritmetica intera e non floating point!
If(num>100)
– num = 24
else
– num=0;
14
Esercizi di programmazione
Il resto giusto
Scrivere un programma che prenda in
ingresso un numero di centesimi da
restituire al cliente e produca in uscita il
numero di monete da: 2 e 1 Euro, e da 50,
20, 10, 5, 2 e 1 centesimi da dare al cliente
Usa aritmetica intera e non floating point!
15
Input floating point
import java.io.*;
class StringToDouble
{
public static void main (String[] args)
{
final String charData = "3.14159265";
double value;
value = Double.parseDouble( charData ) ;
System.out.println("value: " + value +" twice value: " + 2*value );
}
}
Cambierebbe qualcosa se togliessi le virgolette
dall’inizializzazione di charData?
E se invece usassimo la notazione scientifica?
final String charData = "0.314159265E+1";
16
Input floating point da tastiera
import java.io.*;
class InputToDouble
{
public static void main (String[] args) throws IOException
{
String charData;
double value;
BufferedReader
stdin
=
InputStreamReader(System.in));
new
BufferedReader
(new
System.out.println("Enter a double:");
charData = stdin.readLine();
value = Double.parseDouble( charData ) ;
System.out.println("value: " + value +" twice value: " + 2*value );
}
}
17
Il costo di una cena…
import java.io.*;
class RestaurantBill
{
public static void main (String[] args) throws IOException
{
String charData;
double basicCost;
BufferedReader stdin =
new BufferedReader (
new InputStreamReader( System.in ) );
System.out.println("Enter the basic cost:");
charData = stdin.readLine();
basicCost = Double.parseDouble( charData ) ;
System.out.println("basic cost: " + basicCost +
" total cost: " +
(basicCost + basicCost*0.06 + basicCost*0.20));
}
}
Il costo di una cena è dato dal costo di base (inserito
dall’utente) + il 6% di tasse e il 20% di servizio
18
Esercizio di programmazione
Modificare il programma precedente
così che l’utente possa inserire da
tastiera le percentuali per le tasse e il
servizio
19
Java come una calcolatrice…
import java.io.*;
class SquareRoot
{
public static void main (String[] args) throws IOException
{
String charData;
double value;
// read in a double
BufferedReader stdin = new BufferedReader
(new InputStreamReader(System.in));
System.out.print ("Enter a double:");
charData = stdin.readLine();
value = Double.parseDouble( charData ) ;
// calculate its square root
double result = Math.sqrt( value );
// write out the result
System.out.println("square root: " + result );
}
}
20
La classe Math
La classe Math ha molti metodi che possono
tornare utili…
Es: log, sin, cos
 Provali per esercizio
Vuoi saperne di più sulla classe Math?
Controlla la documentazione Java online:
java.sun.com oppure sul tuo java sdk!
Sqrt è descritto così: static double sqrt(double a)
 Qual è il tipo di input? E quale quello di output?
Prova l’esercizio precedente con vari input
Es. 3.5, 9.0, 9, -4, etc.
21
Conversione automatica di tipo
Sqrt() si aspetta un double come parametro di
ingresso. Tuttavia il codice funziona anche se noi gli
passiamo un intero
Il compilatore inserisce automaticamente il codice per la
conversione al tipo giusto
Alla chiamata di sqrt() il parametro passato è di tipo double
Spesso i programmatori usano un cast esplicito:
int x = 9;
System.out.println( Math.sqrt( (double)x ) );
 Come detto, in questo caso il cast non era richiesto
Qual è il risultato di questo frammento?
int x = 1;
int y = 9;
System.out.println( Math.sqrt(x/y) ) );
Il risultato è 0.0, forse non quello che ci saremmo aspettati.
Come possiamo risolvere la cosa?
 Con un cast esplicito
22
Math.cos() e Math.sin() vogliono radianti…
Ma noi siamo abituati a ragionare in gradi…
Usiamo le funzioni di Math
 public static double toRadians(double angdeg)
 public static double toDegrees(double angrad)
import java.io.*;
class CosineCalc
{
public static void main (String[] args) throws IOException
{
String charData;
double degrees;
// read in a double
BufferedReader stdin = new BufferedReader
(new InputStreamReader(System.in));
System.out.print ("Enter degrees:");
charData = stdin.readLine();
degrees = Double.parseDouble( charData ) ;
// calculate its cosine
double result = Math.cos( Math.toRadians(degrees) ); //Nota le funzioni annidate
// write out the result
System.out.println("cosine: " + result );
}
}
23
Esercizi di programmazione
Scrivere un programma che calcola la
velocità (ad un istante che l’utente
specifica in input) di un oggetto lasciato
cadere da una torre
Usa la formula: v = (1/2) g t2
Scrivere un programma che il logaritmo
in base 2 di un numero specificato
dall’utente
Ricorda: log2 X = (loge X) / (loge 2)
24
Esercizi di programmazione
Scrivere un programma che legge da
input 2 numeri e ne produce la media
aritmetica e la media armonica
Formula per la media armonica:
H = 2 / ( 1/X + 1/Y )
25
La gerarchia di classi di java.io
2 gerarchie di classi principali
Basate sul tipo di dato su cui operano
Character streams (16 bit)
– Java.io.Reader e java.io.writer sono le superclassi
abstract
Byte streams (8 bit)
– Java.io.InputStream e java.io.OutputStream
26
Reading and writing…
Reader
int read()
int read(char cbuf[])
int read(char cbuf[], int offset, int length)
Writer
int write(int c)
int write(char cbuf[])
int write(char cbuf[], int offset, int length)
InputStream
int read()
int read(byte cbuf[])
int read(byte cbuf[], int offset, int length)
OutputStream
int write(int c)
int write(byte cbuf[])
int write(byte cbuf[], int offset, int length)
27
The java.io jungle…
28
Using the streams
I/O Streams
Type of I/O
Streams
CharArrayReader
CharArrayWriter
ByteArrayInputStream
ByteArrayOutputStream
Use these streams to read from and write to memory. You create
these streams on an existing array and then use the read and
write methods to read from or write to the array.
StringReader
StringWriter
StringBufferInputStream
Use StringReader to read characters from a String in memory. Use
StringWriter to write to a String. StringWriter collects the
characters written to it in a StringBuffer, which can then be
converted to a String.
StringBufferInputStream is similar to StringReader, except that it
reads bytes from a StringBuffer.
FileReader
FileWriter
FileInputStream
FileOutputStream
Collectively called file streams, these streams are used to read
from or write to a file on the native file system. The section
How to Use File Streams. has an example that uses
FileReader and FileWriter to copy the contents of one file into
another.
Memory
File
Description
29
Using the streams
Data
Conversion
N/A
DataInputStream
DataOutputStream
Read or write primitive data types in a machine-independent format.
See How to Use DataInputStream and DataOutputStream. shows an
example of using these two streams.
Counting
LineNumberReader
LineNumberInputStream
Keeps track of line numbers while reading.
Printing
PrintWriter
PrintStream
Contain convenient printing methods. These are the easiest streams
to write to, so you will often see other writable streams wrapped in
one of these.
Buffering
BufferedReader
BufferedWriter
BufferedInputStream
BufferedOutputStream
Buffer data while reading or writing, thereby reducing the number
of accesses required on the original data source. Buffered streams
are typically more efficient than similar nonbuffered streams and are
often used with other streams.
InputStreamReader
OutputStreamWriter
A reader and writer pair that forms the bridge between byte streams
and character streams.
An InputStreamReader reads bytes from an InputStream and converts
them to characters, using the default character encoding or a
character encoding specified by name.
An OutputStreamWriter converts characters to bytes, using the default
character encoding or a character encoding specified by name and
then writes those bytes to an OutputStream.
You can get the name of the default character encoding by calling
System.getProperty("file.encoding").
Converting between
Bytes and Characters
30
Reading/writing files
import java.io.*;
public class FileCopy {
public static void main(String[] args) throws IOException {
File inputFile = new File("farrago.txt");
//File inputFile = new File("C:\\farrago.txt");
File outputFile = new File("outagain.txt");
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
}
}
31
DataStreams (output)
// write the data out
DataOutputStream out = new DataOutputStream(new
FileOutputStream("invoice1.txt"));
double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
int[] units = { 12, 8, 13, 29, 50 };
String[] descs = { "Java T-shirt",
"Java Mug",
"Duke Juggling Dolls",
"Java Pin",
"Java Key Chain" };
for (int i = 0; i < prices.length; i ++) {
out.writeDouble(prices[i]);
out.writeChar('\t');
out.writeInt(units[i]);
out.writeChar('\t');
out.writeChars(descs[i]);
out.writeChar('\n');
}
out.close();
32
DataStreams (input)
// read it in again
DataInputStream in = new DataInputStream(new
FileInputStream("invoice2.txt"));
double price;
int unit;
StringBuffer desc;
double total = 0.0;
try {
while (true) {
price = in.readDouble();
in.readChar();
// throws out the tab
unit = in.readInt();
in.readChar();
// throws out the tab
char chr;
desc = new StringBuffer(20);
//char lineSep = System.getProperty("line.separator").charAt(0);
char lineSep = '\n';
while ((chr = in.readChar()) != lineSep)
desc.append(chr);
//String descStr = in.readLine();
System.out.println("You've ordered " + unit + " units of " + desc +
" at $" + price);
//System.out.println("You've ordered " + unit + " units of " +
descStr + " at $" + price);
total = total + unit * price;
}
} catch (EOFException e) {
System.out.println("EOF reached!");
}
System.out.println("For a TOTAL of: $" + total);
in.close();
}
33
Scarica

04b I/O