In questa lezione affronteremo delle classi Java per le operazioni di Input e Output
I/O Stream
Un’ I/O Stream rappresenta una generica sorgente di input o output.Uno stream può quindi rappresentare diversi tipi di sorgenti o destinazioni, inclusi file su disco, periferiche, altri programmi e aree di memoria. Gli Stream possono supportare diversi tipi di dati, inclusi bytes, tipi di dati primitivi, caratteri localizzati e oggetti. Alcuni stream non fanno altro che passare dei dati, altri manipolano e trasformano i dati con cui vengono in contatto. Un programma usa un’input stream per leggere dati da una fonte, un oggetto alla volta:
Un programma usa un output stream per scrivere dati in una destinazione, un oggetto alla volta:
Byte Stream
I programmi usano byte streams per realizzare input e output di bytes da 8-bit. Tutte le classi che fanno “stream” sono figlie di InputStream e OutputStream
Esempio 1
[code lang=”java”]
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class EsempioUno {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("input.txt");
out = new FileOutputStream("output.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}
catch(IOException e){
}
finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
[/code]
Il programma consiste fondamentalmente in un semplice loop che legge l’input stream da un file e scrive l’output stream su un file. Il programma visto in precedenza utilizza i Byte Streams a scopo didattico, ma gestendo dei caratteri sarebbe molto più semplice ed efficace usare i character streams. La piattaforma Java memorizza i caratteri usando lo standard Unicode. Il Character stream I/O converte automaticamente il format interno nei formati di caratteri locali.Tutte le classi character stream sono figlie di Reader e Writer.Come con i byte streams, ci sono classi character stream che si specializzano in I/O di file: FileReader e FileWriter.
Esempio 2
[code lang=”java”]
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Esempiodue {
public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("input.txt");
outputStream = new FileWriter("output.txt");
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} catch (IOException e) {
System.err.println(e);
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
[/code]
Solitamente l’ I/O avviene in unità più grandi dei byte o dei caratteri. L’unità più comune di I/O è la linea: una stringa di caratteri con un terminatore di linea alla fine, come (“\r\n”), (“\r”= carriage return), e (“\n”=line feed).
Buffered Stream
i Buffered input streams leggono i dati da un’area di memoria chiamata buffer; le periferiche fisiche vengono chiamate solo all’inizio per riempire il buffer,analogamente i buffered output streams scrivono I dati su un buffer, chiamando in causa le periferiche solo quando strettamente necessario.
Esempio 3
[code lang=”java”]
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
public class EsempioTre {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream =new BufferedReader(new FileReader("input.txt"));
outputStream =new PrintWriter(new FileWriter("output.txt"));
String l;
while ((l =inputStream.readLine()) != null) {
outputStream.println(l);
}
}
catch(IOException e){
System.err.println(e);
}
finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
[/code]
Data streams
Il Data streams supporta l’I/O binario di tipi di dati primitivi (boolean, char, byte, short, int, long, float, e double) e di String values.
Tutti i Data Stream implementano le interfacce DataInput o DataOutput.
Esempio 4
[code lang=”java”]
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.EOFException;
public class EsempioQuattro {
static final String dataFile = "invoicedata";
static final double[] prices = {19.99, 9.99, 15.99, 3.99, 4.99};
static final int[] units = {12, 8, 13, 29, 50};
static final String[] descs = {"Java T-shirt", "Java Mug", "Duke Juggling Dolls", "Java Pin", "Java Key Chain"};
public static void main(String[] args) throws IOException {
DataOutputStream out = null;
try {
out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));
for (int i = 0; i < prices.length; i++) {
out.writeDouble(prices[i]);
out.writeInt(units[i]);
out.writeUTF(descs[i]);
}
} catch (IOException e) {
System.err.println(e);
} finally {
out.close();
}
DataInputStream in = null;
double total = 0.0;
try {
in = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile)));
double price;
int unit;
String desc;
while (true) {
price = in.readDouble();
unit = in.readInt();
desc = in.readUTF();
System.out.format("You ordered % d units of %s at $ % .2f % n",price);
total += unit * price;
}
}
catch (IOException e) {
System.err.println(e);
}
finally {
in.close();
}
}
}
[/code]
Object Stream
Così come i data stream supportano l’I/O di tipi di dati primitivi, così gli Object Streams supportano l’I/O di oggetti. La maggior parte degli Object Streams supportano la serializzazione degli oggetti implementando l’interfaccia Serializable. La serializzazione permette di inserire un’istanza di una classe in uno stream mantenendo tutti i dati e i riferimenti che ha l’oggetto in quel momento. Le classi Object Stream sono ObjectInputStream e ObjectOutputStream ed implementano ObjectInput e ObjectOutput.che sono interfacce di DataInput e DataOutput. Questo significa che tutti i metodi di gestione delle primitive dei Data Stream sono supportati anche dagli object streams.
Esempio 5
[code lang=”java”]
import java.io.*;
import java.math.BigDecimal;
import java.util.Calendar;
public class EsempioCinque {
static final int[] units = {12, 8, 13, 29, 50};
static final String dataFile = "invoicedata";
static final BigDecimal[] prices = {
new BigDecimal("19.99"),
new BigDecimal("9.99"),
new BigDecimal("15.99"),
new BigDecimal("3.99"),
new BigDecimal("4.99")};
static final String[] descs = {"Java T-shirt",
"Java Mug",
"Duke Juggling Dolls",
"Java Pin",
"Java Key Chain"};
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));
out.writeObject(Calendar.getInstance());
for (int i = 0; i < prices.length; i++) {
out.writeObject(prices[i]);
out.writeInt(units[i]);
out.writeUTF(descs[i]);
}
} finally {
out.close();
}
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(dataFile)));
Calendar date = null;
BigDecimal price;
int unit;
String desc;
BigDecimal total = new BigDecimal(0);
date = (Calendar) in.readObject();
System.out.format("On %tA, %<tB%<te, %<tY:%n", date);
try {
while (true) {
price = (BigDecimal) in.readObject();
unit = in.readInt();
desc = in.readUTF();
System.out.format("You ordered %d units of %s at $%.2f%n", unit, desc, price);
total = total.add(price.multiply(new BigDecimal(unit)));
}
} catch (EOFException e) {
System.err.println(e);
}
System.out.format("For a TOTAL of:$%.2f%n", total);
} finally {
in.close();
}
}
}
[/code]