Presentazione - Luca Andrea Ludovico

Lezione 14
Lettura e scrittura di file
Programmazione per la Musica | Prof. Luca A. Ludovico
Leggere e scrivere file in Java
• Obiettivo della lezione è saper aprire in lettura e
scrittura file binari.
• Possibili applicazioni: import/export di contenuti
musicali rispetto a strutture dati interne, salvataggio
della configurazione, interfacciamento con altri
sistemi, …
• Il primo passaggio è istanziare un oggetto della classe
File, dopodiché è possibile istanziare un oggetto della
classe BufferedReader che prende questo file come
argomento in ingresso.
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
La classe File
• La classe File fornisce una rappresentazione astratta
del percorso (pathname) di una cartella (directory) o
di un documento (file).
• Sistemi operativi e interfacce utilizzano stringhe
dipendenti dal sistema in uso. Questa classe mette a
disposizione un’astrazione comunque gerarchica ma
indipendente dal sistema.
• Esempio: nei percorsi si usa il separatore “/” in Unix,
ma Windows ammette anche “\”
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
La classe File
• Un percorso può essere assoluto o relativo. Quando è
assoluto, contiene intrinsecamente tutte le
informazioni per localizzare un file. Se invece è
relativo, deve essere interpretato sulla base di altre
informazioni.
• Di default, le classi nel package java.io risolvono i
percorsi relativi rispetto alla directory corrente.
Tipicamente, si tratta della cartella in cui si invoca la
Java Virtual Machine.
– In NetBeans, il path relative fa riferimento alla cartella del
progetto, ad esempio JavaApplication1.
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Costruttori e metodi della classe File
• Costruttori: File(String pathname), File(URI uri), …
• boolean canExecute()
• boolean canRead()
• boolean canWrite()
testano i permessi da parte dell’applicazione
• boolean delete()
• void deleteOnExit()
cancellano il file o la cartella, istantaneamente o alla
chiusura della virtual machine
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Verifica dell’esistenza
• Nella lettura di file, la principale problematica
da gestire è il fatto che si tratti realmente di
un file.
• Il modo più semplice è invocare il metodo
boolean isFile(), ed esiste anche boolean
isDirectory()
• In alternativa, il metodo boolean File.exists()
verifica se il file o la directory esistono.
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Altri metodi della classe File
• La classe File mette a disposizione un gran numero di
metodi per gestire documenti e cartelle. Ad esempio:
– String getName() restituisce il nome del file o directory
– String getParent() dà il nome della cartella padre
– String getPath() converte il nome astratto in un percorso a
stringa
– boolean isHidden() verifica se si tratta di file nascosto
– long lastModified() restituisce l’istante di ultima modifica
– long length() dà la dimensione del file
– String[] list() dà l’elenco di file e cartelle contenute nella
cartella denotata dal path corrente (con numerose varianti…)
– …
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
La classe FileReader
• FileReader è pensata per leggere del testo carattere
per carattere.
• Costruttori: FileReader(File file), FileReader(String
fileName), …
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
La classe BufferedReader
• Un BufferedReader legge testo da un flusso di
caratteri in ingresso, in modo da rendere efficiente la
lettura sequenziale di caratteri e righe
• Sarebbe possibile specificare anche la dimensione del
buffer, ma quella di default è sufficientemente
capiente per la maggior parte delle applicazioni
• Tra i principali metodi: int read() legge un singolo
carattere, String readLine() legge una riga di testo e
long skip(long n) salta nella lettura un certo numero di
caratteri
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Lettura di un file riga per riga
File file = new File("miofile.txt");
if (file.isFile()) {
try {
FileReader fileReader = new FileReader (file)
BufferedReader bufReader = new BufferedReader(fileReader);
String line;
// lettura del file di testo riga per riga
while ((line = bufReader.readLine()) != null) {
; // operazioni su line
}
bufReader.close(); // rilascio delle risorse
} catch (IOException e) {
}
}
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
ESEMPIO
ParseLines.java
Il software carica da un file in formato TXT diversi modelli di scala, codificati uno
per riga nella forma
nome_modello1/pc,nc;pc,nc;…
nome_modello2/pc,nc;pc,nc;…
e dopo averli caricati all’interno di opportune strutture dati li visualizza nella
console.
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
La classe StringTokenizer
• Negli esempi visti in precedenza si è spesso utilizzato
il metodo String[] split(String regex), ove regex è
un’espressione regolare.
• Una valida alternativa è costituita dalla classe
StringTokenizer del package java.util, che fornisce
metodi per spezzare una stringa in token. Un token è
una sequenza massimale di caratteri che non contiene
un delimitatore.
– Ad esempio, è possibile leggere una frase in input e
considerare lo spazio come delimitatore dei token, in modo
da ottenere un array di singole parole.
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Costruttori
• Un’istanza di StringTokenizer viene creata indicando:
– la stringa da spezzare,
– l'eventuale insieme di delimitatori (per default " \t\n\r\f")
– se i delimitatori sono token o no
• StringTokenizer (String str, String delim, boolean returnDelims)
Crea un tokenizer per 'str', che usa i caratteri in 'delim', come
delimitatori. 'returnDelims' indica se restituire i delimitatori
come token oppure scartarli.
• StringTokenizer (String str, String delim)
Come sopra, con returnDelims == false
• StringTokenizer (String str)
Come sopra, con delim == " \t\n\r\f"
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Principali metodi
• Un’istanza di StringTokenizer scorre la stringa
sequenzialmente dall'inizio alla fine, restituendo i token
uno alla volta. I metodi principali sono:
• boolean hasMoreTokens()
restituisce true se c'e' ancora un token da restituire
• String nextToken()
restituisce il prossimo token
• String nextToken(String delim)
restituisce il prossimo token, usando i caratteri di 'delim'
come delimitatori
• int countTokens()
restituisce il numero di token che restano da esaminare
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
ESEMPIO
EasyScore.java
Il software interpreta una rappresentazione testuale di una partitura, in cui ogni
riga corrisponde a uno strumento (monodico) e ogni gruppo di caratteri separato da
virgole a una pulsazione di valore ritmico predefinito (ad esempio da un ottavo).
Le altezze sono scritte in notazione anglosassone (ad es. C4 rappresenta il Do della
quarta ottava, e Eb5 il Mi bemolle della quinta).
Le pause sono contrassegnate come note «degeneri» tramite la lettera R.
E’ possibile introdurre spazi per allineare le note dal punto di vista grafico, ma
questi devono essere stralciati dal parsing della melodia.
Le durate si ricavano dal numero di virgole che separano le stringhe.
Ad esempio, l’incipit di Fra’ Martino sarebbe:
C4,D4,E4,C4,C4,D4,E4,C4,E4,F4,G4, ,E4,F4,G4, ,G4, ,G4
R, , , , , , , ,C4,D4,E4,C4,C4,D4,E4,C4,E4,F4,G4
Si utilizzi la classe StringTokenizer.
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Scrittura di file su disco
• Si può scrivere su file usando due modalità: carattere
per carattere e per stringhe, in analogia con le
tecniche di lettura da file.
• FileWriter scrive singoli caratteri
• BufferedWriter scrive intere stringhe
• Il comportamento è molto simile, dato che FileWriter
eredita i metodi di scrittura dalla superclasse:
java.io.OutputStreamWriter
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Esempio di scrittura con FileWriter
import java.io.*;
class ScriviPitches {
public static void main(String args[])
throws IOException {
FileWriter w;
w = new FileWriter("pitches.txt");
w.write('A'); // carattere per carattere
w.write('G');
w.flush();
// scarica su file
}
}
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
Esempio di scrittura con BufferedWriter
import java.io.*;
class ScriviPitches {
public static void main(String args[])
throws IOException {
FileWriter w;
w = new FileWriter("pitches.txt");
BufferedWriter b;
b = new BufferedWriter (w);
b.write("Do Re Mi\nFa Sol La");
b.write("Si");
b.flush();
}
}
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file
ESERCIZIO
Data una struttura dati che contiene un ArrayList di note (ciascuna caratterizzata
da nome della nota, ottava, stato di alterazione, durata) si trovi il modo per
scrivere queste informazioni separatamente allineandole in colonna:
• Prima riga: nomi delle note
• Seconda riga: stato di alterazione
• Terza riga: ottava
• Quarta riga: numeratore
• Quinta riga: denominatore
Programmazione per la Musica - Prof. Luca A. Ludovico
14. Lettura e scrittura di file