Streams e Input/output Scansione e Formattazione di un testo



Scaricare 0.52 Mb.
14.11.2018
Dimensione del file0.52 Mb.


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 diretto



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


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()
    • ...


Scansione

  • Scanner

  • non solo per input da file …



Scansione



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



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



Output Formattato

  • PrintWriter

  • non solo per output sul file …



Output Formattato



Esempio

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



File LineNumberer.java



File LineNumberer.java



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?



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.



Streams

  • Due modalità di memorizzazione e codifica dei dati:

    • formato testo
    • formato binario
  • Due corrispondenti gerarchie di streams nella libreria java.io



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'


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


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


Streams di Testo

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

  • Write.write(char c)

    • scrive il carattere sulla stream


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



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


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


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


Input/output strutturato

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



DataOutputStreams

  • Scrive un array di double su un file



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



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


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


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


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


writeObject()

  • Scrive un intero oggetto sulla stream

  • Anche una lista viene scritta da una sola writeObject



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


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


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



File Serialtester.java



File Serialtester.java



Serializzazione user-defined

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

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



Serializzazione user-defined

  • Il campo hash è transient,

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



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)


Nome: serializzazione corretta



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


File ad Accesso Casuale

  • Permette di accedere a punti arbitrari di un file

  • Solo per file memorizzati su disco

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



Accesso Casuale



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.getFilePointer() restituisce la posizione corrente del file pointer

  • f.length() restituisce la lunghezza del file



RandomAccessFile

  • Memorizza dati in formato binario

  • readInt e writeInt leggono e scrivono interi su 4 bytes

  • readDouble e writeDouble utilizzano 8 bytes



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 …



Esempio

  • Calcolo del numero di conti sul file



Esempio

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



Esempio

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



File BankDatatester.java



File BankDatatester.java



File BankDatatester.java



File BankDatatester.java



File BankData.java



File BankData.java



File BankData.java



File BankData.java



File BankData.java



File BankData.java



File BankData.java



Output



Esempio: Text Editor Grafico



Menu



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



Menu Items



Struttura dei Menu Items



EditorMenuItem



Clear/Cut/Copy/Paste



Clear/Cut/Copy/Paste



Find



Find



Quit



FileMenuItem



JFileChooser



Open



EditBuffer



EditBuffer



EditBuffer





Condividi con i tuoi amici:


©astratto.info 2019
invia messaggio

    Pagina principale