80
Streams e Input/output

Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Embed Size (px)

Citation preview

Page 1: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streamse

Input/output

Page 2: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

• Scansione e Formattazione di un testo

• Streams Testuali e Binarie

• Streams di dati primitivi

• Streams di oggetti (serializzazione)

• File ad accesso diretto

Page 3: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Scansione

Scanner

• Da Java 1.5 il modo più semplice di leggere da una stream di tipo testo: Uno scanner suddivide la stream in tokens utilizzando

delimitatori (per default spazi, tabs, newlines …) i tokens possono essere convertiti in valor di tipo

primitivo e stringa utilizzando i metodi della classe

Continua…

Scanner in = new Scanner(File(“input.txt“));

Page 4: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Scansione

Scanner

• Per effettuare la scansione dell’input utilizziamo i metodi forniti dalla classe

• Metodi di scansione generica String next(), bool hasNext()

cercano il prossimo token (ignorando i delimitatori)

• Metodi di scansione specifica per tipo int nextInt(), bool hasNextInt() ...

Continua…

Page 5: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Scansione

Scanner

• non solo per input da file …

Continua…

Page 6: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Scansione

Page 7: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Output Formattato

• Per formattare un file di testo costruiamo un PrintWriter sul file

• Se il file esiste al momento della creazione il contenuto viene cancellato

• Se il file non esiste, la chiamata al costruttore crea un nuovo file, vuoto

PrintWriter out = new PrintWriter("output.txt");

Continua…

Page 8: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Output Formattato

• Utilizziamo print e println per scrivere con PrintWriter:

• File aperti (in scrittura) devono essere sempre chiusi

• Altrimenti non abbiamo garanzie che l’output sia effettuato

out.println(29.95); out.println(new Rectangle(5, 10, 15, 25)); out.println("Hello, World!");

out.close();

Continua…

Page 9: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Output Formattato

PrintWriter

• non solo per output sul file …

Continua…

Page 10: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Output Formattato

PrintWriter out = new PrintWriter("output.txt");

Page 11: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Esempio

• Legge tutte le linee di un file (di tipo testo) e le copia in output precedute dal numero di linea

Continua…

Mary had a little lamb Whose fleece was white as snow. And everywhere that Mary went, The lamb was sure to go!

/* 1 */ Mary had a little lamb /* 2 */ Whose fleece was white as snow. /* 3 */ And everywhere that Mary went, /* 4 */ The lamb was sure to go!

Page 12: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File LineNumberer.java

import java.io.FileReader;import java.io.IOException;import java.io.PrintWriter;import java.util.Scanner;

public class LineNumberer{ public static void main(String[] args) { Scanner console = new Scanner(System.in); System.out.print("Input file: "); String inputFileName = console.next(); System.out.print("Output file: "); String outputFileName = console.next();

try {

Continua…

Page 13: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File LineNumberer.java FileReader reader = new FileReader(inputFileName); Scanner in = new Scanner(reader); PrintWriter out = new PrintWriter(outputFileName); int lineNumber = 1; while (in.hasNextLine()) { String line = in.nextLine(); out.println("/* " + lineNumber + " */ " + line); lineNumber++; } out.close(); } catch (IOException exception) { System.out.println("Error processing file:"+ exception); } }}

Page 14: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Domande

• Che succede se forniamo lo stesso nome per i due file di input e output?

• Che succede se il nome fornito dall’utente non corrisponde ad alcune file?

Page 15: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Risposte

• Creando il PrintWriter si azzera il contenuto del file di output. Anche il file di input è quindi nullo, e dunque il ciclo termina immediatamente.

• Il programma cattura una FileNotFoundException, stampa un messaggio di errore e termina.

Page 16: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams

• Due modalità di memorizzazione e codifica dei dati: formato testo formato binario

• Due corrispondenti gerarchie di streams nella libreria java.io

Page 17: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams di Testo

• Utilizzate per la lettura scrittura di testo

• Sono sequenze di caratteri l’intero 12.345 è memorizzato come la

seguenza di caratteri '1' '2' '3' '4' '5'

Continua…

Page 18: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams di Testo

• Reader, Writer classi astratte che fanno da radici per gerarchia delle stream di testo per le operazioni di input e output

• Molte sottoclassi, alcune già viste FileReader, Scanner, ...

FileWriter, PrintWriter ...

Continua…

Page 19: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams di Testo

Continua…

• Le classi Reader, Writer forniscono i metodi base per l’input/output

• Reader.read() restituisce il prossimo carattere, come intero -1 se non esiste un nuovo carattere (nd of file) si blocca in attesa di input da tastiera

Reader reader = new FileReader(“input.txt”);int next = reader.read(); char c; if (next != -1) c = (char) next;

Page 20: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams di Testo

• Le classi Reader, Writer forniscono i metodi base per l’input/output

• Write.write(char c) scrive il carattere sulla stream

Page 21: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams Binarie

• Utilizzate la manipolazione di dati in formato binario

• Dati rappresentati come sequenze di bytes l’intero 12.345 è memorizzato come la

seguenza di quattro bytes 0 0 48 57

• Rappresentazione più compatta ed efficiente

Continua…

Page 22: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams Binarie

• InputStream, OutputStream classi astratte che fanno da radici per gerarchia delle stream binarie per le operazioni di input e output

• Anche qui molte sottoclassi concrete FileInputStream, ObjectInputStream, ... FileOutputStream,ObjectOutputStream, ...

Continua…

Page 23: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Streams Binarie

Continua…

• Le classi InputStream, OutputStream forniscono i metodi base per l’input/output

• InputStream.read() restituisce il prossimo carattere, come intero -1 se non esiste un nuovo carattere (end of file)

• OutputStream.write(byte b) scrive b sullo stream

Page 24: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

DataStreams

• Utilizzate per leggere e scrivere in formato binario di tipi primitivi byte, char, short, ..., double, boolean,

• Due classi: DataInputStream, DataOutputStream

• Forniscono metodi per manipolare dati primitivi, readBoolean / writeBoolean readChar / writeChar readInt / writeInt ... / ...

Page 25: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Input/output strutturato

• Per operazioni più complesse utilizziamo le sottoclassi, come classi decorators

Reader reader = new FileReader(“input.txt”));Scanner input = new Scanner(reader);

Writer writer = new FileWriter(“output.txt”));PrintWriter output = new PrintWriter(writer));

InputStream is = new FileInputStream(“in.bin”));DataInputStream dis = new DataInputStream(is);

OutputStream os = new FileOutputStream(“out.bin”));DataOutputStream dos = new DataOutputStream(os);

Page 26: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

DataOutputStreams

• Scrive un array di double su un file

void writeData(double[] data, String file) throws IOException {

DataOutputStream out = new DataOutputStream(

new FileOutputStream(file));out.writeInt(data.length());for (int i = 0; i < data.length; i++)

out.writeDouble(data[i]);out.close();

}

Page 27: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

DataInputStreams

• Legge un file di double, in cui il primo elemento è un intero che rappresenta il numero di valori contenuti nel file

• restituisce un array con i valori letti

double[] readData(String file) throws IOException {DataInputStream in =

new DataInputStream(new FileInputStream(file));

double[] data = new double[in.readInt()]; for (int i = 0; i < data.length; i++)

data[i] = in.readDouble();in.close(); return data;

}

Page 28: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File Streams

• Permettono di utilizzare files come streams

• Due coppie di classi FileInputStream / FileOutputStream FileReader / FileWriter

• Ognuna di queste classi permette di costruire una stream su un file a partire da: una stringa, il nome del file un oggetto di tipo File un oggetto di tipo FileDescriptor

Page 29: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

La classe File

• Rappresentazione astratta del nome e proprietà di files e directories.

• Diversi sistemi operativi utilizzano diverse sintassi per i nomi di files: la classe File fornisce una rappresentazione indipendente dal sistema

• Un nome è rappresentato da una stringa prefissa che rappresenta la radice la radice del file

system : ad esempio “/” in unix e “\\” per una sequenza di zero o più nomi, ciascuno dei quali rappresenta

un passo sul cammino al file. Tutti i nomi sono directories, ad eccezione dell’ultimo che può essere una directory o un file

Page 30: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

ObjectStreams

• Estensioni delle DataStreams a valori di tipo riferimento

• Classi: ObjectInputStream e ObjectOutputStream

• serializzazione/deserializzazione conversione di un oggetto in/da una stream di bytes

• Metodi ObjectOutputStream.writeObject() ObjectInputStream.readObject()

Page 31: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

ObjectStreams

• writeObject(Object obj): scrive sulla stream una sequenza di bytes

corrispondente al grafo che costituisce obj il grafo include tutti i campi primitivi dell’oggetto e tutti

gli oggetti raggiungibili da riferimenti presenti in obj; esclusi i campi marcati transient

• Object readObject() legge dalla stream una sequenza di bytes che

rappresenta un grafo e restituisce l’oggetto corrispondente

Page 32: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

writeObject()

• Scrive un intero oggetto sulla stream

• Anche una lista viene scritta da una sola writeObject

BankAccount b = . . .; ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("bank.dat")); out.writeObject(b);

ArrayList<BankAccount> a = new ArrayList<BankAccount>(); // ... aggiungi BankAccounts ad a ... out.writeObject(a);

Page 33: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

readObject()

• Restituisce un riferimento di tipo Object Necessario ricordare i tipi degli oggetti scritti sulla

stream per leggerli ed utilizzare cast

• può lanciare ClassNotFoundException eccezione controllata necessario catturare o dichiarare

Continued…

BankAccount b = (BankAccount) in.readObject();

Page 34: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Serializable

• Oggetti scritti su una object stream devono appartenere a classi che implementano l’interfaccia Serializable

• Serializable è una interfaccia marker non ha metodi, segnala una proprietà.

class BankAccount implements Serializable { . . . }

Continua…

Page 35: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Serializable

• Ogni oggetto scritto sulla stream viene associato ad un numero seriale

• Se lo stesso oggetto viene scritto due volte, la seconda volta si scrive solo il numero seriale, non l’oggetto

• In fase di lettura, ogni input alloca un nuovo oggetto, a meno che la lettura non incontri un numero seriale duplicato, nel qual caso si restituisce un riferimento allo stesso oggetto

Page 36: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File Serialtester.java

public static void main(String[] args) throws IOException, ClassNotFoundException { Bank bank; File f = new File("bank.dat"); if (f.exists()) { ObjectInputStream in = new ObjectInputStream (new FileInputStream(f)); bank = (Bank) in.readObject(); in.close(); } else { bank = new Bank(); bank.addAccount(new BankAccount(1001, 20000)); bank.addAccount(new BankAccount(1015, 10000)); }

Continua…

Page 37: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File Serialtester.java

// Esegui un deposito BankAccount a = firstBankOfJava.find(1001); a.deposit(100); System.out.println(a.getAccountNumber() + ":" + a.getBalance()); a = firstBankOfJava.find(1015); System.out.println(a.getAccountNumber() + ":" + a.getBalance());

ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream(f)); out.writeObject(firstBankOfJava); out.close(); }}

Page 38: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Serializzazione user-defined

• In alcune situazioni la serializzazione default può risultare scorretta/inefficiente.

• hash è transient, perché si può calcolare dal nome

class Nome implements Serializable { private String nome; private transient int hash; public Nome (String nome) { this.nome = nome; hash = nome.hashCode();} . . . }

Continua…

Page 39: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Serializzazione user-defined

• Il campo hash è transient,

• Ma allora deserializzando un Nome perdiamo il suo codice hash …

class Nome implements Serializable { private String nome; private transient int hash; public Nome (String nome) { this.nome = nome; hash = nome.hashCode();} . . . }

Continua…

Page 40: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Serializzazione user-defined

• Sia C la nostra classe Serializable

• Definiamo in C due metodi: void writeObject(ObjectOutputStream) void readObject(ObjectInputStream)

• Invocati automaticamente da ObjectOutputStream.writeObject(Object o)quando l’argomento ha tipo C

ObjectInputStream.readObject()per leggere argomenti scritti da C.writeObject(ObjectOutputStream)

Page 41: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Nome: serializzazione corretta

class Nome implements Serializable {

private String nome;private transient int hash;

public Nome (String nome) { this.nome = nome; hash = name.hasCode();}

private void writeObject(ObjectOutputStream out)throws IOException

{ out.writeUTF(nome); }

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException

{ nome = in.readUTF(); hash = nome.hashCode();}}

Continua…

Page 42: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Nome: serializzazione corretta

• writeObject / readObject dichiarano IOException invocano metodi che potrebbero lanciarle.

• readObject dichiara ClassNotFoundException : deserializzazione richiede la costruzione oggetti di classi che

devono essere caricate (e quindi trovate) per invocarne i costruttori

• sono private: per protezione il processo di serializzazione bypassa questo vincolo, per

invocare comunque i due metodi, utilizzando i meccanismi di riflessione per disattivare i livelli di accesso

Page 43: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File ad Accesso Casuale

• Permette di accedere a punti arbitrari di un file

• Solo per file memorizzati su disco System.in e System.out non supportano queste

operazioni

• Ogni file su disco ha uno stato che determina la posizione corrente di lettura e/o scrittura

Page 44: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Accesso Casuale

Page 45: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

RandomAccessFile

• Possiamo aprire un file in diverse modalità Read-only ("r") Read-write ("rw") Write-only ("w")

• Il metodo seek() permette di spostare il file-pointer ad una specifica posizione

RandomAccessFile f = new RandomAcessFile("bank.dat","rw");

f.seek(n);

Continua…

Page 46: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

RandomAccessFile

• f.getFilePointer() restituisce la posizione corrente del file pointer

• f.length() restituisce la lunghezza del file

// tipo "long" perchè un file può avere grandi dimensioni

long n = f.getFilePointer();

fileLength =

Continua…

Page 47: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

RandomAccessFile

• Memorizza dati in formato binario

• readInt e writeInt leggono e scrivono interi su 4 bytes

• readDouble e writeDouble utilizzano 8 bytes

Page 48: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Esempio

• Utilizziamo un file ad accesso casuale per memorizzare un insieme di conti bancari memorizziamo solo la parte dati di ciascun conto numero di conto e saldo

• Il programma permette di selezionare un conto ed eseguire operazioni di deposito/prelievo …

Page 49: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Esempio

• Calcolo del numero di conti sul file

public int size() throws IOException { return (int) (file.length() / RECORD_SIZE); // RECORD_SIZE = 12 bytes: // 4 bytes per il numero // 8 bytes for il saldo

}

Page 50: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Esempio

• Accesso (in lettura) all’n-esimo conto sul file

public BankAccount read(int n) throws IOException { file.seek(n * RECORD_SIZE); int accountNumber = file.readInt(); double balance = file.readDouble(); return new BankAccount(accountNumber, balance); }

Page 51: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Esempio

• Accesso (in scrittura) all’n-esimo conto

public void write(int n, BankAccount account) throws IOException { file.seek(n * RECORD_SIZE); file.writeInt(account.getAccountNumber()); file.writeDouble(account.getBalance()); }

Page 52: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankDatatester.java

import java.io.IOException;import java.io.RandomAccessFile;import java.util.Scanner;

/** Test per file ad accesso diretto. Un loop di interazione con l’utente in cui si agisce su un conto esistente o se ne crea uno nuovo..*/public class BankDataTester{ public static void main(String[] args) throws IOException { Scanner in = new Scanner(System.in); BankData data = new BankData(); try Continua…

Page 53: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankDatatester.java

{ data.open("bank.dat"); boolean done = false; while (!done) { System.out.print("Account number: "); int accountNumber = in.nextInt(); System.out.print("Amount to deposit: "); double amount = in.nextDouble(); int position = data.find(accountNumber); BankAccount account; if (position >= 0) { account = data.read(position); account.deposit(amount);

Continued…

Page 54: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankDatatester.java

System.out.println("new balance=" + account.getBalance()); } else // Add account { account = new BankAccount(accountNumber, amount); position = data.size(); System.out.println("adding new account"); } data.write(position, account); System.out.print("Done? (Y/N) "); String input = in.next(); if (input.equalsIgnoreCase("Y")) done = true; } } Continua…

Page 55: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankDatatester.java

finally { data.close(); } } }

Page 56: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankData.java

import java.io.IOException;import java.io.RandomAccessFile;

/** * Una classe associata ad un file contenente i dati . */ public class BankData { /** * Costruisce una BankData senza associarla ad un file */ public BankData() { file = null; } Continua…

Page 57: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankData.java

/** * Apre il file di dati. * @param il nome del file con i dati */ public void open(String filename) throws IOException { if (file != null) file.close(); file = new RandomAccessFile(filename, "rw"); }

Continua…

Page 58: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankData.java

/** * Restituisce il numero di conti sul file */ public int size() throws IOException { return (int) (file.length() / RECORD_SIZE); } /** * Chiude il file */ public void close() throws IOException { if (file != null) file.close(); file = null; } Continua…

Page 59: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankData.java

/** * Legge un record dal file. */ public BankAccount read(int n) throws IOException { file.seek(n * RECORD_SIZE); int accountNumber = file.readInt(); double balance = file.readDouble(); return new BankAccount(accountNumber, balance); }

Continua…

Page 60: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankData.java

/** * Trova la posizione del conto con il dato numero * @result = la posizione, -1 se il conto non viene trovato */ public int find(int accountNumber) throws IOException { for (int i = 0; i < size(); i++) { file.seek(i * RECORD_SIZE); int a = file.readInt(); if (a == accountNumber) // trovato return i; } return -1; // nessun match sull’intero file }

Continua…

Page 61: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankData.java

/** Salva un record sul tile @param n l’indice del conto sul file @param il conto da salvare */ public void write(int n, BankAccount account) throws IOException { file.seek(n * RECORD_SIZE); file.writeInt(account.getAccountNumber()); file.writeDouble(account.getBalance()); } private RandomAccessFile file;

Continua…

Page 62: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

File BankData.java

public static final int INT_SIZE = 4; public static final int DOUBLE_SIZE = 8; public static final int RECORD_SIZE = INT_SIZE + DOUBLE_SIZE;}

Page 63: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Output

Account number: 1001 Amount to deposit: 100 adding new account Done? (Y/N) N Account number: 1018 Amount to deposit: 200 adding new account Done? (Y/N) N Account number: 1001 Amount to deposit: 1000 new balance=1100.0 Done? (Y/N) Y

Page 64: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Esempio: Text Editor Grafico

MenuItem

Page 65: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Menu

Menu

MenuBar

MenuItem

Page 66: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Menu Items

• Aggiungiamo i menu items e i menu in cascata con il metodo add add():

• Un menu item genera eventi eventi, più precisamente ActionEvents

JMenuItem fileExitItem = new JMenuItem("Exit"); fileMenu.add(fileExitItem);

Continua…

Page 67: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Menu Items

• Aggiungiamo quindi un listener a ciascun item:

• Il listener viene associato agli items del menu, non al menu o alla barra dei menu

fileExitItem.addActionListener(listener);

Page 68: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Struttura dei Menu Items

:

EditorMenuItem<abstract>

PasteMenuItemClearMenuItem

OpenMenuItem

FileMenuItem<abstract>

SaveMenuItem

ActionListener<interfaccia>

FindMenuItem

JMenuItem

QuitMenuItem

Page 69: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

EditorMenuItem/** EditorMenuItem: un menu item generico */

abstract class EditorMenuItem extends JMenuItem implements ActionListener

{ // il buffer su cui opera il menu item private EditBuffer buffer;

public EditorMenuItem(String label, EditBuffer buff) { super(label);buffer = buff;addActionListener(this);

}

protected EditBuffer getBuffer() { return buffer; }

// no actionPerformed(): la classe e` abstract}

Page 70: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Clear/Cut/Copy/Paste

class ClearMenuItem extends EditorMenuItem { public ClearMenuItem(String label, EditBuffer buff) { super(label, buff); }

public void actionPerformed(ActionEvent e) { getBuffer().clear(); }}

class CutMenuItem extends EditorMenuItem { public CutMenuItem(String label, EditBuffer buff) { super(label, buff); }

public void actionPerformed(ActionEvent e) { getBuffer().cut(); }}

Continua…

Page 71: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Clear/Cut/Copy/Paste

class CopyMenuItem extends EditorMenuItem { public CopyMenuItem(String label, EditBuffer buff) { super(label, buff); }

public void actionPerformed(ActionEvent e) { getBuffer().copy(); }}

class PasteMenuItem extends EditorMenuItem { public PasteMenuItem(String label, EditBuffer buff) { super(label, buff); } public void actionPerformed(ActionEvent e) { getBuffer().paste(); }}

Page 72: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Find

/** * FindMenuItem: genera un dialog per cercare * una stringa nella text area */

class FindMenuItem extends EditorMenuItem { public FindMenuItem(String label, EditBuffer buff) { super(label, buff); } // . . . metodo actionPerformed . . .

}

Continua…

Page 73: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Find

public void actionPerformed(ActionEvent e) { String s = JOptionPane.showInputDialog(this,"Search:"); if ( s != null ) { int index = buffer.findFromCaret(s);

if ( index == -1 ) { int response = JOptionPane.showConfirmDialog(this,

"Not found. Wrapped Search?"); if ( response == JOptionPane.YES_OPTION ) { index = buffer.findFromStart(s); if ( index == -1 ) JOptionPane.showMessageDialog(thi "Not Found"); }

} }

Page 74: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Quit

/** QuitMenuItem: esci dall'editor */

class QuitMenuItem extends JMenuItem implements ActionListener{ private EditFrame frame; public QuitMenuItem(String label, EditFrame frame) {

super(label);this.frame = frame; addActionListener(this);

}

public void actionPerformed(ActionEvent e) {if (frame.confirmQuit()) System.exit(0); return;

}}

Page 75: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

FileMenuItem

abstract class FileMenuItem extends EditorMenuItem {

public FileMenuItem(String label, EditBuffer buff) {super(label, buff);

}

public File chooseFile() { File chosen = null; JFileChooser chooser = new JFileChooser();chooser.setDialogTitle("Open");int result = chooser.showDialog(null,“Open");if ( result == JFileChooser.APPROVE_OPTION ) { chosen = chooser.getSelectedFile();}return chosen;

}}

Page 76: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

JFileChooser

Page 77: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

Openclass OpenMenuItem extends FileMenuItem { public OpenMenuItem(String label, EditBuffer buff) {

super(label, buff); } public void actionPerformed(ActionEvent e) {

File f = chooseFile(); if ( f == null) return;getBuffer().setFile(f); try { getBuffer().setText(""); getBuffer().openFile(); } catch (IOException exc) { JOptionPane.showMessageDialog(null,

"Could not open File");}

}}

Page 78: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

EditBufferpublic class EditBuffer extends JTextArea{ private File f; // il file associato al buffer

public EditBuffer(File initFile, int rows, int cols) { super("", rows, cols); f = initFile; setLineWrap(true); setFont(new Font("Courier", Font.PLAIN, 14));

if (f == null) return; try {

openFile(); } catch (IOException e) { JOptionPane.showMessageDialog(this,"File not Found!"); } } . . . Continua…

Page 79: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

EditBuffer

public void openFile() throws IOException { Scanner opened = null; try { FileReader r = new FileReader(f); opened = new Scanner(r); while ( opened.hasNextLine() ) {

String s = opened.nextLine(); append(s+"\n");

}} finally { if (opened != null) opened.close(); }

}

Continua…

Page 80: Streams e Input/output. Scansione e Formattazione di un testo Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione)

EditBuffer

public void saveBuffer() throws IOException, NoFileSelectedException {

PrintWriter p = null;if (f == null) throw new NoFileSelectedException(); try { FileWriter w = new FileWriter(f); p = new PrintWriter(w); p.print(getText()); } finally { if (p != null) p.close();}

}