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