Scopo di questo esercizio è consentirvi di far pratica con i seguenti argomenti studiati durante il corso:
L'implementazione del file system da voi realizzata deve consentire le seguenti operazioni:
Quest'interfaccia rappresenta il generico nodo del file system, indipendentemente dal fatto che si tratti di un file oppure una directory. File e directory saranno implementazioni dell'interfaccia; per indicare che una classe implementa un'interfaccia si utilizza la parola chiave implements come in questo esempio: public class MyFile implements FSNode { .. codice .. }.
L'interfaccia definisce un nome convenzionale per l'insieme delle diverse classi che la implementano e un insieme minimale di metodi che queste devono fornire. Ogni classe che implementa un'interfaccia la specializza, ovvero definisce un caso particolare, con proprietà proprie e può fornire metodi (public) in più.
Per esempio, nel nostro caso sia file che directory sono elementi del file system, però i primi hanno nome, estensione e contenuto, le seconde hanno un nome, un flag che indica se sono o meno scrivibili e come contenuto un insieme di altri file o directory. L'unica informazione comune alle due classi è il nome e il fatto che le intendiamo essere entrambe elementi di una stessa struttura (il file system). In questo caso avere a disposizione un nome unico con cui identificare i due tipi di elemento può però essere molto utile nell'implementazione.
L'interfaccia contiene i prototipi dei metodi che devono
essere implementati in tutte le classi facenti capo ad essa, nel nostro caso:
public interface FSNode {
void setNome(String s);
String getNome();
}
Per indicare (ad esempio) che la classe MyFile
implementa una certa interfaccia si utilizza la sintassi:
public class MyFile implements FSNode {
private String name; // variabile che conterra' il nome del file
private ... // altre variabili necessarie per realizzare la classe
public void setNome(String nome) {
... implementazione del metodo ...
}
public String getNome() {
... implementazione del metodo ...
}
... // altri metodi utili
}
Si noti che la classe contiene un'implementazione dei metodi dichiarati nell'interfaccia
che ne rispetta il profilo (stessi nomi, stessi tipi di argomenti, stessi valori ritornati),
non è in vece necessario che i nomi dei parametri dei metodi delle implementazioni
siano identici a quelli usati nei corrispondenti prototipi dell'interfaccia.
La classe MyFile è un'implementazione dell'interfaccia FSNode
e definisce le proprietà di un file (nome, estensione e
contenuto), che devono essere gestite tramite opportuni metodi get e set
(ad esempio: public String getEstensione() e public void setEstensione(String n).
La classe MyFile deve contenere tutti i metodi che consentono di operare su di un file, come ad esempio la stampa a video delle informazioni relative al file.
La classe MyDirectory è un'implementazione dell'interfaccia FSNode e definisce le proprietè di una directory, ovvero il suo nome e un booleano che indica se la directory è scrivibile o meno. Attenzione: il fatto che una directory sia scrivibile significa che è possibile cambiarne il contenuto, cioè creare o rimuovere file e directory al suo interno. Se si cerca di creare (per esempio) un file in una directory non scrivibile il metodo deve ritornare un'opportuna eccezione. Come sempre, le proprietè di un oggetto MyDirectory devono essere gestite tramite opportuni metodi get e set (ad esempio: public boolean getScrivibile() e public void setScrivibile(boolean flag)).
Oltre a un insieme di proprietà una directory ha anche un "contenuto", che consiste in un insieme di oggetti di tipo FSNode (in questo modo possiamo comprendere sia file che directory in un unico insieme). L'insieme degli elementi FSNode può essere realizzato come array di lunghezza definita all'atto della chiamata del costruttore. Attenzione: se un utente richiede di inserire un file in una directory il cui array di FSNode è pieno, occorre ridimensionare l'array e cioè crearne uno nuovo la cui dimensione è maggiore di quella del precedente di un numero di unità a piacere. Nel nuovo array verrà copiato quello vecchio e verrà aggiunta la componente in più richiesta.
La classe MyDirectory deve contenere tutti i metodi che consentono di operare su di una directory, come creazione e cancellazione di file/directory figlie, stampa del contenuto, ecc.
La classe FileSystem va definita per estensione della classe MyDirectory. In particolare, supporremo che il disco di cui il file system fornisce una vista abbia dimensione finita, quindi la classe FileSystem dovrà contenere una variabile intera che indica la quantità di spazio libero ancora disponibile. Questa variabile verrà usata per decidere se è possibile creare nuovi file (lo spazio occupato da un file è pari al numero di caratteri del suo contenuto) e nuove directory (supporremo per convenzione che una directory occupa uno spazio pari a 10 unità). Inoltre occorre definire una variabile di istanza che contiene un riferimento alla directory di lavoro. Il valore iniziale di questa variabile dovrà consentire l'accesso alla radice del FileSystem stesso.
La classe FileSystem deve fornire metodi che consentono di eseguire tutti i comandi utente elencati a inizio pagina (la maggior parte dei quali lavorerà sulla directory di lavoro corrente): creazione e rimozione di un file, creazione e rimozione di una directory, stampa del cammino assoluto corrispondente alla working directory, modifica della working directory, dir, find e tree.La solita. Consente di interagire con l'utente.