La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Streams e Input/output

Presentazioni simili


Presentazione sul tema: "Streams e Input/output"— Transcript della presentazione:

1 Streams e Input/output

2 Scansione e Formattazione di un testo
Streams Testuali e Binarie Streams di dati primitivi Streams di oggetti (serializzazione) File ad accesso diretto

3 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 Scanner in = new Scanner(File(“input.txt“)); Continua…

4 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…

5 Scansione Scanner non solo per input da file … Continua…

6 Scansione

7 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…

8 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…

9 Output Formattato PrintWriter non solo per output sul file … Continua…

10 Output Formattato PrintWriter out = new PrintWriter("output.txt");

11 Esempio Legge tutte le linee di un file (di tipo testo) e le copia in output precedute dal numero di linea 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! Continua…

12 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…

13 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);

14 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?

15 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.

16 Streams Due modalità di memorizzazione e codifica dei dati:
formato testo formato binario Due corrispondenti gerarchie di streams nella libreria java.io

17 Streams di Testo Utilizzate per la lettura scrittura di testo
Sono sequenze di caratteri l’intero è memorizzato come la seguenza di caratteri '1' '2' '3' '4' '5' Continua…

18 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…

19 Streams di Testo 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; Continua…

20 Streams di Testo Le classi Reader, Writer forniscono i metodi base per l’input/output Write.write(char c) scrive il carattere sulla stream

21 Streams Binarie Utilizzate la manipolazione di dati in formato binario
Dati rappresentati come sequenze di bytes l’intero è memorizzato come la seguenza di quattro bytes Rappresentazione più compatta ed efficiente Continua…

22 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…

23 Streams Binarie 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 Continua…

24 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 ... / ...

25 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);

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

27 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; }

28 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

29 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

30 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()

31 ObjectStreams writeObject(Object obj): Object readObject()
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

32 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);

33 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 BankAccount b = (BankAccount) in.readObject(); Continued…

34 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…

35 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

36 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…

37 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); ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream(f)); out.writeObject(firstBankOfJava); out.close(); }

38 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…

39 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…

40 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)

41 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…

42 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

43 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

44 Accesso Casuale

45 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…

46 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…

47 RandomAccessFile Memorizza dati in formato binario
readInt e writeInt leggono e scrivono interi su 4 bytes readDouble e writeDouble utilizzano 8 bytes

48 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 …

49 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 }

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

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

52 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…

53 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…

54 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…

55 File BankDatatester.java
finally { data.close(); }

56 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…

57 File BankData.java /** * Apre il file di dati.
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…

58 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…

59 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…

60 File BankData.java /** * Trova la posizione del conto con il dato numero = 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…

61 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…

62 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; }

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

64 Esempio: Text Editor Grafico
MenuItem

65 Menu MenuBar MenuItem Menu

66 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…

67 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);

68 Struttura dei Menu Items
: EditorMenuItem <abstract> PasteMenuItem ClearMenuItem OpenMenuItem FileMenuItem SaveMenuItem ActionListener <interfaccia> FindMenuItem JMenuItem QuitMenuItem

69 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

70 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) { getBuffer().cut(); } Continua…

71 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) { getBuffer().paste(); }

72 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…

73 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"); }

74 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;

75 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;

76 JFileChooser

77 Open class 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");

78 EditBuffer public 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…

79 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…

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


Scaricare ppt "Streams e Input/output"

Presentazioni simili


Annunci Google