Appunti java 10.4. pag.143 La classe File e gli attributi di directory e file Questa classe, molto utile per operare con i file su disco, consente di accedere alle directory, verificare e acquisire le caratteristiche dei file presenti, cambiarne gli attributi, cancellare e rinominare file. File Costruttori File(String) File(String, String) NOTE Crea un file di Path e Nome indicati nella stringa. Separa il path “genitore” – 1° string Dal path “figlio” – 2° string Metodi di lettura boolean exists() boolean canRead() boolean canWrite() boolean isDirectory() boolean isFile() boolean isHidden() String getAbsolutePath() String getName() String getParent() String[] list() long length() Verifica l’esistenza del file con cui è invocata. Esempio: String s=”autoexec.bat”; File f=new File(s); if (f.exists()) … Verifica se il file con cui è invocata e di sola lettura. Esempio: if (f.canRead()) … Idem per la lettura e scrittura. Verifica se si tratta di Directory Verifica se si tratta di File Verifica se il File è nascosto. Restituisce una stringa con il path completo del file. Restituisce una stringa con il nome del File. Restituisce una stringa con il solo path del file. Restituisce un array di stringhe con tutti i file e le sottodirectory se invocato con un nome di directory. File f=new File(“C:\”); String s[]=f.list(); Restituisce la lunghezza in byte del file invocante. Metodi di settaggio boolean createNewFile() boolean delete() void deleteOnExit() boolean mkdir() boolean renameTo(File) boolean setReadOnly() Crea un file vuoto. Il boolean è true se l’operazione ha avuto successo. Cancella il file. Setta il file per la sua cancellazione all’uscita dal programma. Crea una directory Rinomina il file invocante con il nome del parametro. Setta il file in sola lettura. Il boolean è true se l’operazione è riuscita. Appunti java pag.144 esempio 7. “realizzare un programma che acquisisca una stringa corrispondente al nome fisico di un file presente su disco C:/.. e stampi un opportuno messaggio <Il file non esiste>, <Il file è lungo xxx byte. E’ di lettura/scrittura.>.” Richieste: a) Risolverlo rispettando la seguente scomposizione main() leggi() dove leggi() è la procedura di acquisizione del nome file; (vedi procedure di acquisizione da console nei capitoli precedenti). b) Risolverlo con il solo main() acquisendo la stringa come argomento del main(). Soluzione a) import java.io.*; class cap10_es_07_a{ static String leggi(){ int ch; StringBuffer S=new StringBuffer(); System.out.println("\n\n\nImmetti il nome del file cercato:"); try { while ((ch=System.in.read()) != '\n') // (1) S=S.append((char)ch); S=S.deleteCharAt(S.length()-1); // (2) } catch (IOException e) { } // (3) return S.toString(); } public static void main(String arg[]){ String nome=leggi(); File f=new File(nome); if (!f.exists()) System.out.println("NON ESISTE il file "+nome); else { long dim=f.length(); System.out.print("Il file: "+nome+" e' lungo:"+dim+" byte."); if (f.canWrite()) System.out.println(" E' di lettura e scrittura."); else System.out.println(" E' di sola lettura."); } } } // (4) // (5) // (6) // (7) Esecuzione: Il programma deve acquisire l’input da console e quindi in RealJava è necessario eseguire il <Run With Console>. I risultati sono i seguenti: Commento al codice: Le note (1) e (3) mostrano una modalità di gestione delle eccezioni di IO, modalità diversa da quella adottata in precedenti input da console. La nota (2) evidenzia la necessità di eliminare il carattere di INVIO inserito dal ciclo di lettura nel Buffer. Le note da (4) a (7) evidenziano rispettivamente il costruttore del file, il metodo che ne testa l’esistenza su disco, il metodo che ne determina la lunghezza in byte e infine il metodo che determina se il file è di sola lettura o anche di scrittura. Appunti java pag.145 Soluzione b) import java.io.*; class cap10_es_07_b{ public static void main(String arg[]){ String nome=""; if (arg.length>=1) nome=arg[0]; // (1) File f=new File(nome); // (2) if (!f.exists()) // (3) System.out.println("NON ESISTE il file "+nome); else { long dim=f.length(); // (4) System.out.print("Il file: "+nome+" e' lungo:"+dim+" byte."); if (f.canWrite()) // (5) System.out.println(" E' di lettura e scrittura."); else System.out.println(" E' di sola lettura."); } } } Esecuzione: Prima di eseguire in RealJava il programma è necessario aprire l’opzione <File: Preferences:> e attivare <Ask for input ….> come dalle immagini sottostanti: L’opzione attivata farà comparire all’avvio del programma un campo in cui immettere una o più stringhe che sono gli argomenti del main(). La stringa “c.\mio.txt” viene inserita nell’array arg[] del main() alla componente 0. L’esecuzione stampa sulla finestra di output il messaggio desiderato. Commento al codice: La note (1) mostra come acquisire il nome del file dall’array arg[]. Le note da (2) a (5) mostrano i metodi della classe File. Appunti java pag.146 esempio 8. “realizzare un programma che acquisisca due stringhe corrispondenti al nome di una Directory e all’estensione dei file da ricercare su disco C:/.. e stampi la lista dei file della directory che hanno l’estensione desiderata.” Richieste: Risolverlo acquisendo le due stringhe come argomento del main(). Codifica: import java.io.*; class cap10_es_08{ public static void main(String arg[]){ String nome="",est=""; // if (arg.length>=1) nome=arg[0]; // if (arg.length>=2) est=arg[1]; // File f=new File(nome); // File a[]=f.listFiles(); // for (int i=0; i<a.length;i++){ String s=a[i].toString(); // s=s.substring(s.length()-4); // boolean b=(s.equalsIgnoreCase(est)); // if ((a[i].isFile()) && b) // System.out.println(a[i].getName()); } } } (1) (2) (3) (4) (5) (6) (7) (8) (9) Esecuzione: Commento al codice: Le note (1),(2) e (3) mostrano come acquisire i due argomenti del main() e assegnarli alle variabili nome (della Directory) e est (estensione dei file da ricercare). Le note (4) e (5) sono rispettivamente, il costruttore che genera la Directory nella quale ricercare, e il metodo che estrae la lista di tutti i file contenuti in essa. Le note (6), (7) e (8) evidenziano rispettivamente che è necessario trasformare il nome del file a[i] in una stringa, estrarre dalla stringa i 4 caratteri finali che coincidono con l’estensione e infine confrontare tale estensione con quella cercata (est) generando il flag booleano b. Appunti java pag.147 La nota (9) mostra infine che il nome del file viene stampato solo se b==true ovvero se ha l’estensione desiderata. esempio 9. “Si desidera costruire un programma che consenta di creare un file di testo immettendo dati da tastiera o di appendere testo in coda se il file è presente su disco.” Richieste: a) Il nome del file deve essere immesso come parametro del main(); b) Se il file non esiste, dopo un opportuno messaggio, deve essere possibile l’immissione elementare di righe di testo da tastiera fino a quando non si invia un EOF (Ctrl-z);; c) Se il file esiste, dopo l’opportuna segnalazione, il file viene stampato sulla console e quindi si rende disponibile l’immissione fino a quando non si invia un EOF (Ctrl-z); d) Al termine dell’immissione, a scopo di controllo il metodo stampa() mostra il risultato. Codifica: import java.io.*; class cap10_es_09{ public static void stampa(String n_fil)throws IOException { RandomAccessFile in=new RandomAccessFile(n_fil,"r"); System.out.print("\nil file lungo "+in.length()+" byte \n"); String dat; while ((dat=in.readLine())!=null) System.out.println(dat); in.close(); } public static void main(String arg[])throws IOException{ String nome="";int ch; RandomAccessFile io;InputStreamReader in; // (1) if (arg.length>=1) nome=arg[0]; // (2) File f=new File(nome); // (3) if (f.exists()){ // (4) stampa(nome); io=new RandomAccessFile(nome,"rw"); // (5) System.out.println("Il file ESISTE, Appendi:"); io.seek(io.length()); // (6) } else { io=new RandomAccessFile(nome,"rw"); // (5) System.out.println("Il file NON ESISTE, Immetti:"); } in=new InputStreamReader(System.in); // (7) while ((ch=in.read()) != -1) io.writeByte(ch); // (8) io.setLength(io.getFilePointer()); // (9) io.close(); stampa(nome); } } Commento al codice: (1) definisce i file io e lo stream di inpeu in. (2) acquisisce il nome del file. (3) crea l’oggetto File necessario per testarne l’esistenza con il metodo di nota (4). Le note (5) e (6) creano rispettivamente il file di output e posizionano il puntatore per appendere. Le note (7) e (8) mostrano il ciclo di acquisizione da tastiera e scrittura nel file io. Il ciclo si interrompe se da tastiera si preme Ctrl-Z. (9) chiude il file con EOF. Appunti java pag.148 10.E – Esercizi Esercizi che usano, in lettura o scrittura, File di caratteri, di testo o di record di lunghezza fissa in modo elementare usando la sola console. [main() unico] Si desidera costruire un programma che “acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco, stampi il il testo e il numero delle righe di cui è costituito sulla console." Richieste: realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). Fare uso del metodo readln() per leggere e contare le righe. 10.2. Si desidera costruire un programma che “acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco, lo stampi su console eliminando i marcatori di end_of_line". Indicazioni: Fare uso del metodo read() per leggere i singoli caratteri e ricordare che i marcatori di fine linea sono o '\n' oppure '\r' oppure la coppia \r\n. Richieste: realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). 10.3. Si desidera costruire un programma che “acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco, ne conti le vocali che contiene e stampi sia il risultato che il testo su console.". Indicazioni: Fare uso del metodo read() per leggere i singoli caratteri. Richieste: realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). 10.4. Si desidera costruire un programma che “acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco, ne generi uno nuovo e lo memorizzi su disco appendendo al termine una nuova riga che contenga la frase <ultima riga appesa>. Stampi il nuovo testo su console.". Richieste: realizzare il solo main() e acquisire il nome dei file di Input e di Output come parametri del main(String args[]). 10.5. Si desidera costruire un programma che “Legga un file di testo da disco e Generi un nuovo file di testo e lo memorizzi sul disco eliminando dal file di input i marcatori di fine linea. Stampi il file ottenuto su console.". Richieste: realizzare il solo main() e acquisire il nome dei file di Input e di Output come parametri del main(String args[]). 10.6. Si desidera costruire un programma che “acquisito il nome di un file di interi (comprensivo del percorso path) memorizzato su disco, stampi su console gli interi separati da uno spazio." Richieste: realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). 10.7. Si desidera costruire un programma che “generi e memorizzi su disco un file di interi costituito da 20 numeri generati casualmente e compresi tra 10.000 e 99.999, stampi su console il file come verifica." Richieste: realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). 10.1. Appunti java pag.149 Si desidera costruire un programma che “acquisito il nome di un file di interi (comprensivo del percorso path) memorizzato su disco, stampi su console gli interi separati da uno spazio e successivamente sovrascriva ogni intero superiore a 1000 con 999 e ristampi il file su Console." Richieste: realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). 10.8. Esercizi con l'uso della classe File: 10.9. Si desidera costruire un programma che “acquisito il nome di un file qualsiasi (comprensivo del percorso path) memorizzato su disco, stampi un messaggio di esistenza/non esistenza e indichi la sua lunghezza in byte”. Richieste: o realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). 10.10. Si desidera costruire un programma che “acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco, stampi un messaggio di esistenza/non esistenza, indichi la sua lunghezza in byte e stampi testo sulla console." Richieste: realizzare il solo main() e acquisire il nome file come parametro del main(String args[]). Esercizi di riscrittura o fusione di file 10.11. Si desidera costruire un programma che “acquisito il nome di un file di double (comprensivo del percorso path) memorizzato su disco, stampi su console i numeri separati da uno spazio e successivamente costruisca un nuovo file che contiene numeri interi derivati dal primo file per troncamento. Ristampi in nuovo file su Console." Richieste: realizzare il solo main() e acquisire il nome dei due file come parametri del main(String args[]). 10.12. Si desidera costruire un programma che “acquisito il nome di due file di double (comprensivo del percorso path) memorizzati su disco, crei il file fusione che contiene in ogni record la somma dei corrispondenti valori dei due file origine. Stampi i tre file per verificare la correttezza del procedimento." Nota: Se i due file di double sono di lunghezza diversa il programma deve completare il file fusione con i soli numeri residui. Richieste: realizzare il solo main() e acquisire il nome dei tre file come parametri del main(String args[]). 10.13. desidera costruire un programma che “acquisito il nome di un file di record costituiti da una Stringa di dimensione 20 e da un intero, che rappresentano rispettivamente una città e i suoi abitanti e di un secondo file con lo stesso tipo di record che rappresenta l'incremento/decremento subito dalla popolazione. Fondere in un nuovo file i dati della popolazione aggiornati e stampare i tre file per verificare la correttezza del procedimento." Nota: Si faccia l'ipotesi che il file popolazione sia ordinato alfabeticamente rispetto al nome della città e che così sia anche per il file aggiornamento. Non necessariamente l'aggiornamento contiene tutte le città (una città potrebbe non aver subito modifiche). Appunti java pag.150 Richieste: o Realizzare il solo main() e acquisire il nome dei due file popolazione e aggiornamento come parametri del main(String args[]). o Dopo aver usato un file temporaneo per la fusione, si dovrà cancellare il vecchio popolazione e aggiornamento e rinominare il file di fusione chiamandolo ancora popolazione. Problemi che usano File di caratteri o di testo in modo elementare su Frame con Eventi. (classe finestra con eventi – comandi semplici) 10.14. Come in 10.9, si desidera costruire un programma che “acquisito il nome di un file qualsiasi (comprensivo del percorso path) memorizzato su disco, stampi in un campo di una frame il nome del file e un messaggio di esistenza/non esistenza con l'indicazione della sua lunghezza in byte”. Richieste: o il main(String args[]) deve acquisire il nome file come parametro di input e quindi chiamare il costruttore della classe finestra che mostra il risultato. o la classe finestra con i metodi dis_gui() fa_eventi() deve gestire il solo evento windowOpened() al quale corrisponde il programma che stampa quanto richiesto. 10.15. Come in 10.10. si desidera costruire un programma che “acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco, stampi su una frame un messaggio di esistenza/non esistenza, indichi la sua lunghezza in byte e stampi testo contenuto." Richieste: o il main(String args[]) deve acquisire il nome file come parametro di input e quindi chiamare il costruttore della classe finestra che mostra il risultato. o la classe finestra con i metodi dis_gui() fa_eventi() deve gestire il solo evento windowOpened() al quale corrisponde il programma che stampa quanto richiesto. 10.16. Come il 10.1 ma con output su finestra. Richieste: mostrare il messaggio in una text area, gestendo l'evento windowOpened(). 10.17. Come il 10.2 ma con output su finestra. Richieste: mostrare il testo in una text area, gestendo l'evento windowOpened(). 10.18. Come il 10.3 ma con output su finestra. Richieste: mostrare il testo e quanto richiesto in una text area, gestendo l'evento windowOpened(). 10.19. Come il 10.4 ma con output su finestra. Richieste: mostrare il file di input in una text area e rimostrare il file di output in una text area distinta. 10.20. Come il 10.5 ma con output su finestra. Richieste: mostrare il file di input in una text area e rimostrare il file di output in una text area distinta. Problemi che usano File e Stream per progettare semplici classi con input/output su console. a) trattamento di testi e parole b) trattamento di file con record di lunghezza costante c) trasformazioni di file di testo in file di record e viceversa Appunti java pag.151 Categoria a) 10.21. si desidera realizzare un programma che “acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco, lo filtri restituendo a richiesta una delle seguenti funzionalità: il numero di parole che contiene, il numero di token numerici, il numero di righe, il numero di caratteri e il testo stesso sotto forma di stringa." Richieste: o Progettare una classe filtro che fornisca le funzionalità richieste utilizzando al suo interno le funzionalità della classe StreamTokenizer. o Disegnare la classe prima di codificarla. o Realizzare un main() che testi il funzionamento delle funzionalità realizzate. 10.22. Si desidera realizzare un programma che “Costruisca l'indice analitico di una parola di un testo. Acquisito il nome di un file di testo (comprensivo del percorso path) memorizzato su disco e la parola xxx si deve ottenere l'indice della parola nella forma: xxx pag. yy, zz, kk." Richieste: o progettare (o ampliare) la classe filtro che fornisca le funzionalità richieste utilizzando al suo interno le funzionalità della classe StreamTokenizer, supporre che ad ogni fine pagina corrisponda un marcatore particolare ad esempio '\'." o Disegnare la classe prima di codificarla. o realizzare un main() che testi il funzionamento dei metodi realizzati. Categoria b) 10.23. Si desidera realizzare un programma che “Generi, con la funzione random, un file di dati costituito da numeri decimali (comprensivo del percorso path) memorizzato su disco e ne possa calcolare i seguenti numeri caratteristici: la media aritmetica, il massimo e il minimo. Deve inoltre fornire la possibilità di stampa del file" Richieste: o Progettare una classe (indici) che esibisca le funzionalità richieste dal testo (Definire i Casi D'uso). o Disegnare la classe/i prima di codificarla. o Realizzare un main() che ne testi il funzionamento. 10.24. Si desidera realizzare un programma che “Acquisisca da tastiera e generi un file di dati costituito da numeri interi lo memorizzi su disco e lo stampi." Indicazioni: o utilizzare per l'input da tastiera dei numeri lo Stream di input più adatto. Richieste: o progettare una classe (file_interi) che esibisca le funzionalità richieste dal testo (Definire i Casi D'uso). o Disegnare la classe/i prima di codificarla. o Realizzare un main() che ne testi il funzionamento. 10.25. Si desidera realizzare un programma che “Acquisisca da tastiera e generi un file di dati costituito da un'entità (record?) formato da una Stringa <nome> e da un intero che rappresenta il <peso> in Kg. Dopo averlo memorizzato su disco lo legga, calcoli la media e stampi sul video di Appunti java pag.152 fianco a ciascun nome il differenziale tra il suo peso e la media. Es Tizio – 0.500 Kg, Caio +7.5 Kg. ecc." Richieste: o progettare una classe che esibisca le funzionalità richieste dal testo (Definire i Casi D'uso). o Disegnare la classe/i prima di codificarla. o realizzare un main() che ne testi il funzionamento. 10.26. Si desidera realizzare un programma come il precedente che “Acquisisca da tastiera e generi un file di dati costituito da entità di tipo Stringa <nome> e da un intero che rappresenta il <peso> in Kg <idem es. 10.25> . Successivamente generare un nuovo file che memorizzi Nome, Peso e Differenziale e lo stampi" Indicazioni: o Idem. Richieste: o idem Categoria c) 10.27. Si desidera realizzare un programma che “Disponendo in input di un file di interi (o generandolo con la funzione random) lo trasformi in un file di testo con i numeri separati da uno spazio. Si richiede di disporre di una funzionalità che mostri a video il file di testo generato." Richieste: o progettare una classe che esibisca le funzionalità richieste dal testo (Definire i Casi D'uso). o Disegnare la classe/i prima di codificarla. o realizzare un main() che ne testi il funzionamento. 10.28. Si desidera realizzare un programma che “Dopo aver generato (random) un file di interi, lo trasformi in un file di testo con i numeri separati da uno spazio. Si richiede di disporre di una funzionalità che legga il file di testo e restituisca un array di interi." Richieste: o progettare una classe che esibisca le funzionalità richieste dal testo (Definire i Casi D'uso). o Disegnare la classe/i prima di codificarla. o realizzare un main() che ne testi il funzionamento e Stampare l'array come verifica." 10.29. Si desidera realizzare un programma che “Disponendo in input di un file di record, costituito da una Stringa nome e dal peso intero, <come esercizio 10.25>, lo trasformi in un file di testo nel quale ogni riga contenga Nome e Peso separati da uno spazio. Si desidera disporre della funzionalità di stampa del testo." Richieste: o progettare una classe che esibisca le funzionalità richieste dal testo (Definire i Casi D'uso). o Disegnare la classe/i prima di codificarla. o realizzare un main() che ne testi il funzionamento. Problemi che usano File e Stream per progettare semplici classi con input/output su Frame con Eventi. Appunti java pag.153 Si desidera realizzare un programma che "consenta all'utente di immettere interi separati su ogni riga in un'area di una finestra e quindi li memorizzi, alla pressione di una coppia di Pulsanti a scelta o come file di testo o come file di interi." Richieste: o all'evento di chiusura della frame, se non è stato salvato il lavoro in una delle due modalità, deve comparire una finestra di dialogo (Frame Dialog) che informi che non si è salvato e a conferma consenta di proseguire ugualmente o di ritornare alla frame per salvare. o Disegnare Casi d'Uso e Classi e successivamente Codificare. o realizzare un main() che ne testi il funzionamento. 10.31. Si desidera realizzare un programma che "consenta all'utente di portare in un'area di una finestra un file di Interi (uno per ogni riga del campo) e quindi dopo eventuali modifiche li memorizzi, alla pressione di una coppia di Pulsanti a scelta o come file di testo o come file di interi." Richieste: o all'evento di chiusura della frame, se non è stato salvato il lavoro in una delle due modalità, deve comparire una finestra di dialogo (Frame Dialog) che informi che non si è salvato e a conferma consenta di proseguire ugualmente o di ritornare alla frame per salvare. o Disegnare Casi d'Uso e Classi e successivamente Codificare. o realizzare un main() che ne testi il funzionamento. 10.32. Si desidera realizzare un programma "che immetta in un'area della frame una coppia Nome,Numero separati da spazio e quindi li memorizzi, alla pressione di una coppia di Pulsanti a scelta, come file di testo (ogni riga Nome Numero) o come file di record." Richieste: o all'evento di chiusura della frame, se non è stato salvato il lavoro in una delle due modalità, deve comparire una finestra di dialogo (Frame Dialog) che informi che non si è salvato e a conferma consenta di proseguire ugualmente o di ritornare alla frame per salvare.. o Disegnare Casi d'Uso e Classi e successivamente Codificare. o realizzare un main() che ne testi il funzionamento. 10.30.