I File in Java: differenze tra le versioni

Da Bioingegneria Elettronica e Informatica.
(Creata pagina con "== Introduzione == Java fornisce classi e metodi per scrivere e leggere dati da files; le tipologie di files che si possono trovare sono sostanzialmente due: * flussi di testo...")
 
(Classe RandomAccessFile)
 
(21 versioni intermedie di uno stesso utente non sono mostrate )
Riga 1: Riga 1:
 +
'''Vitoantonio Bevilacqua''' [mailto:vitoantonio.bevilacqua@poliba.it vitoantonio.bevilacqua@poliba.it]
 +
 +
'''Antonio Brunetti''' [mailto:antonio.brunetti@poliba.it  antonio.brunetti@poliba.it]
 +
 +
'''Gianpaolo Francesco Trotta''' [mailto:gianpaolofrancesco.trotta@poliba.it  gianpaolofrancesco.trotta@poliba.it]
 +
 +
<span style="color:red;font-weight:bold">Pagina in lavorazione</span>
 +
 
== Introduzione ==
 
== Introduzione ==
 
Java fornisce classi e metodi per scrivere e leggere dati da files; le tipologie di files che si possono trovare sono sostanzialmente due:
 
Java fornisce classi e metodi per scrivere e leggere dati da files; le tipologie di files che si possono trovare sono sostanzialmente due:
* flussi di testo - sequenze di caratteri;
+
* file di testo;
* flussi binari - una sequenze di byte con corrispondenza uno ad uno con quelli della periferica esterna.
+
* file binari.
 +
Grazie alle classi fornite da Java, la gestione dell'input/output da file è indipendente dalla piattaforma su cui il programma verrà eseguito; inoltre, le operazioni di I/O sono basate sul concetto di flusso (stream), ovvero una sequenza ordinata di dati che ha una sorgente e una destinazione.
 +
 
 +
Per leggere dati da una sorgente bisogna collegarla a uno stream, dove leggere le informazioni in modo ordinato. Analogamente, per scrivere dati su una destinazione, bisogna collegarla a uno stream in cui inserire i dati in modo sequenziale. All’inizio di queste operazioni occorre aprire lo stream e alla fine occorre chiuderlo.
 +
 
 +
 
 +
== Lettura e scrittura di caratteri con file di testo ==
 +
Introduzione alle classi e ai metodi per la lettura e scrittura di caratteri o byte su file.
 +
 
 +
Di seguito sono riportati due esempi che implementano I/O con i file.
 +
 
 +
=== Lettura da file di testo ===
 +
<syntaxhighlight lang="java" line>
 +
import java.io.*;
 +
 
 +
public class Principale {
 +
 
 +
public static void main(String[] args) {
 +
new Principale().run();
 +
}
 +
 +
public void run() {
 +
/* Per la lettura e scrittura di file,
 +
* si utilizzano le classi di java.io:
 +
* - FileReader (FileInputStream)
 +
* - FileWriter (FileOutputStream)
 +
* che permettono di gestire l'I/O di caratteri o bytes
 +
*/
 +
 +
FileReader file;
 +
try {
 +
// Lettura di file di testo con due letture successive
 +
file = new FileReader("dati.txt");
 +
int carattere = file.read();
 +
int carattere2 = file.read();
 +
 +
System.out.println("Il codice del carattere vale: " + carattere);
 +
System.out.println("Il codice del carattere vale: " + carattere2);
 +
file.close();
 +
 +
// Lettura di tutto il contenuto del file di testo con ciclo while
 +
file = new FileReader("dati.txt");
 +
// Letura di tutti i caratteri all'interno di un file di testo
 +
int next = file.read();
 +
while(next != -1) {
 +
char nextc = (char) next;
 +
                System.out.print(nextc); // stampa il carattere
 +
                next = file.read(); // legge il prossimo carattere
 +
}
 +
file.close();
 +
 +
} catch (IOException e) {
 +
// TODO Auto-generated catch block
 +
e.printStackTrace();
 +
}
 +
}
 +
}
 +
</syntaxhighlight>
 +
 
 +
=== Scrittura su file di testo ===
 +
<syntaxhighlight lang="java" line>
 +
import java.io.FileWriter;
 +
import java.io.IOException;
 +
import java.util.Scanner;
 +
 
 +
public class Principale2 {
 +
 
 +
public static void main(String[] args) {
 +
// TODO Auto-generated method stub
 +
new Principale2().run();
 +
}
 +
 +
public void run() {
 +
/* Per la lettura e scrittura di file,
 +
* si utilizzano le classi di java.io:
 +
* - FileReader (FileInputStream)
 +
* - FileWriter (FileOutputStream)
 +
* che permettono di gestire l'I/O di caratteri o bytes
 +
*/
 +
 +
FileWriter file;
 +
Scanner s = new Scanner(System.in);
 +
try {
 +
// Scrittura su file di testo di numeri acquisiti da tastiera
 +
file = new FileWriter("dati_output.txt");
 +
 +
String num = s.nextLine();
 +
while(!num.equals("-1")) {
 +
file.write(num + " ");
 +
num = s.nextLine();
 +
}
 +
 +
file.close();
 +
 +
System.out.println("Dati scritti e file chiuso");
 +
 +
} catch (IOException e) {
 +
e.printStackTrace();
 +
}
 +
}
 +
}
 +
</syntaxhighlight>
 +
 
 +
=== Scrittura e lettura con file binari ===
 +
<syntaxhighlight lang="java" line>
 +
import java.io.FileInputStream;
 +
import java.io.FileOutputStream;
 +
import java.io.IOException;
 +
import java.util.Scanner;
 +
 
 +
public class Principale3 {
 +
 
 +
public static void main(String[] args) {
 +
// TODO Auto-generated method stub
 +
new Principale3().run();
 +
}
 +
 +
public void run() {
 +
/* Per la lettura e scrittura di file,
 +
* si utilizzano le classi di java.io:
 +
* - FileReader (FileInputStream)
 +
* - FileWriter (FileOutputStream)
 +
* che permettono di gestire l'I/O di caratteri o bytes
 +
*/
 +
 +
FileOutputStream fileOutput;
 +
Scanner s = new Scanner(System.in);
 +
try {
 +
// Scrittura su file binario di numeri acquisiti da tastiera
 +
fileOutput = new FileOutputStream("dati_output.dat");
 +
 +
int num = s.nextInt();
 +
while(num != -1) {
 +
fileOutput.write(num);
 +
num = s.nextInt();
 +
}
 +
 +
fileOutput.close();
 +
System.out.println("Dati scritti e file chiuso");
 +
 +
FileInputStream fileInput;
 +
fileInput = new FileInputStream("dati_output.dat");
 +
 +
int numR = fileInput.read();
 +
while (numR != -1) {
 +
System.out.println("Il numero letto vale: " + numR);
 +
numR = fileInput.read();
 +
}
 +
fileInput.close();
 +
System.out.println("Raggiunta fine del file");
 +
 +
} catch (IOException e) {
 +
// TODO Auto-generated catch block
 +
e.printStackTrace();
 +
}
 +
}
 +
}
 +
</syntaxhighlight>
 +
 
 +
== Lettura e scrittura bufferizzata ==
 +
Per la gestione dell'input/output con i file, è possibile utilizzare metodi di classi che implementano funzionalità di I/O più avanzate. Nello specifico, qui verranno utilizzate le classi BufferedReader e BufferedWriter che, a differenza delle classi precedenti (FileReader e FileWriter), riducono il numero di accessi a file e consentono di scrivere/leggere dati più complessi dei singoli bytes utilizzando dei buffer per memorizzare temporaneamente i dati da scrivere.
 +
 
 +
Di seguito ci sono 2 esempi che implementano la lettura e la scrittura bufferizzata sui file di testo.
 +
 
 +
=== Scrittura bufferizzata su file di testo ===
 +
<syntaxhighlight lang="java" line>
 +
import java.io.BufferedWriter;
 +
import java.io.FileWriter;
 +
import java.io.IOException;
 +
import java.io.PrintWriter;
 +
import java.util.Scanner;
 +
 
 +
public class Principale4 {
 +
 
 +
public static void main(String[] args) {
 +
// TODO Auto-generated method stub
 +
new Principale4().run();
 +
}
 +
 +
public void run() {
 +
/* Le classi FileReader e FileWriter forniscono i metodi di base
 +
* per leggere o scrivere caratteri su file.
 +
* Non è conveniente usarle direttamente nei programmi perché
 +
* non permettono di leggere/scrivere direttamente
 +
* dati più complessi come stringhe e numeri.
 +
*/
 +
 +
/* Per ovviare a questo problema di possono utilizzare classi che
 +
* implementano funzionalità di I/O più avanzate.
 +
* - BufferedReader
 +
* - BufferedWriter
 +
* usano un buffer per memorizzare temporaneamente i caratteri da leggere/scrivere,
 +
* in modo da ridurre il numero di accessi al file;
 +
*
 +
* - PrintWriter
 +
* fornisce i metodi print e println, che permettono di scrivere qualunque dato Java,
 +
* convertendolo automaticamente in stringa.
 +
*/
 +
 +
// Scrittura di dati su file
 +
FileWriter fileOutput;
 +
BufferedWriter bufferWriter;
 +
PrintWriter printWriter;
 +
Scanner s = new Scanner(System.in);
 +
try {
 +
// Scrittura su file testo di numeri acquisiti da tastiera
 +
fileOutput = new FileWriter("dati_output2.txt");
 +
bufferWriter = new BufferedWriter(fileOutput);
 +
printWriter = new PrintWriter(bufferWriter);
 +
 +
int num = s.nextInt();
 +
while(num != -1) {
 +
printWriter.println(num);
 +
num = s.nextInt();
 +
}
 +
 +
System.out.println("Dati scritti");
 +
 +
// Proviamo con un vettore
 +
int[] v = {1, 2, 3, 4, 5};
 +
// L'istruzione seguente non stampa gli elementi del vettore, ma solo il valore utilizzato come reference
 +
printWriter.print(v);
 +
/* Il seguente ciclo for permette la stampa su file di testo degli elementi contenuti nel vettore
 +
* for (int i = 0; i < 5; i++) {
 +
* printWriter.print(v[i] + " ");
 +
* }
 +
*/
 +
System.out.println("Vettore scritto");
 +
printWriter.close();
 +
 +
} catch (IOException e) {
 +
// TODO Auto-generated catch block
 +
e.printStackTrace();
 +
}
 +
}
 +
}
 +
</syntaxhighlight>
 +
 
 +
=== Lettura bufferizzata da file di testo ===
 +
<syntaxhighlight lang="java" line>
 +
import java.io.BufferedReader;
 +
import java.io.FileReader;
 +
import java.io.IOException;
 +
 
 +
public class Principale5 {
 +
 
 +
public static void main(String[] args) {
 +
// TODO Auto-generated method stub
 +
new Principale5().run();
 +
}
 +
 +
public void run() {
 +
/* Le classi FileReader e FileWriter forniscono i metodi basici
 +
* per leggere o scrivere caratteri su file.
 +
* Non è conveniente usarle direttamente nei programmi perché
 +
* non permettono di leggere/scrivere direttamente
 +
* dati più complessi come stringhe e numeri.
 +
*/
 +
 +
/* Per ovviare a questo problema di possono utilizzare classi che
 +
* implementano funzionalità di I/O più avanzate.
 +
* - BufferedReader
 +
* - BufferedWriter
 +
* usano un buffer per memorizzare temporaneamente i caratteri da leggere/scrivere,
 +
* in modo da ridurre il numero di accessi al file;
 +
*
 +
* - PrintWriter
 +
* fornisce i metodi print e println, che permettono di scrivere qualunque dato Java,
 +
* convertendolo automaticamente in stringa.
 +
*/
 +
 +
// Scrittura di dati da file
 +
FileReader fileInput;
 +
BufferedReader bufferReader;
 +
int i, num;
 +
try {
 +
// Lettura da file di testo di numeri
 +
fileInput = new FileReader("dati_output2.txt");
 +
bufferReader = new BufferedReader(fileInput);
 +
 +
String s = bufferReader.readLine();
 +
while (s != null) {
 +
System.out.println(s);
 +
s = bufferReader.readLine();
 +
}
 +
 +
for (i = 0; i < 10; i++) {
 +
// L'istruzione seguente permette di convertire in intero una stringa...
 +
// funzioni analoghe esistono per gli altri tipi di valori
 +
num = Integer.parseInt(bufferReader.readLine());
 +
System.out.println(num);
 +
}
 +
 +
bufferReader.close();
 +
fileInput.close();
 +
 +
} catch (IOException e) {
 +
// TODO Auto-generated catch block
 +
e.printStackTrace();
 +
}
 +
}
 +
}
 +
</syntaxhighlight>
 +
 
 +
== File ad accesso casuale ==
 +
La classe RandomAccessFile permette di accedere in lettura e scrittura a file ad accesso casuale, ovvero permette di muoversi all'interno del file in qualunque posizione si desideri in maniera non sequenziale.
 +
 
 +
Di seguito si trova un esempio che mostra come è possibile utilizzare questa classe.
 +
<syntaxhighlight lang="java" line>
 +
import java.io.IOException;
 +
import java.io.RandomAccessFile;
 +
 
 +
public class Principale6 {
 +
 
 +
public static void main(String[] args) {
 +
new Principale6().run();
 +
}
 +
 +
public void run() {
 +
/* La classe RandomAccessFile permette di istanziare oggetti
 +
* in grado di gestire l'accesso casuale ai file.
 +
* Un oggetto di tipo RandomAccessFile può essere istanziato specificando il percorso del file (o in oggetto di tipo File)
 +
* e la modalità di apertura.
 +
* In questo contesto, le principali modalità di apertura dei file sono:
 +
*  - r: apertura in sola modalità lettura;
 +
*  - rw: apertura in modalità lettura e scrittura. In questo caso, se il file non esiste, esso viene creato.
 +
*/
 +
 
 +
RandomAccessFile raf;
 +
int i, num;
 +
try {
 +
// Scrittura su file binario di numeri acquisiti da tastiera
 +
raf = new RandomAccessFile("datiRandom.dat", "rw");
 +
int[] v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 +
 +
for (i = 0; i < 10; i++) {
 +
// writeInt scrive un numero intero sul file
 +
raf.writeInt(v[i]);
 +
}
 +
 +
raf.close();
 +
 +
raf = new RandomAccessFile("datiRandom.dat", "r");
 +
System.out.println("Il file è grande: " + raf.length() + "bytes");
 +
int first, last;
 +
 +
// readInt legge un numero intero dal file
 +
first = raf.readInt();
 +
 +
// seek permette di muoversi all'interno del file
 +
raf.seek(raf.length() - 4);
 +
 +
 +
last = raf.readInt();
 +
raf.close();
 +
 +
System.out.println("Il primo numero vale: " + first);
 +
System.out.println("L'ultimo numero vale: " + last);
 +
 +
} catch (IOException e) {
 +
// TODO Auto-generated catch block
 +
e.printStackTrace();
 +
}
 +
}
 +
}
 +
</syntaxhighlight>
 +
 
 +
== Lettura e Scrittura su File ==
 +
Di seguito è riportato un semplice esempio per la gestione dell'input/output da file, sia di testo, sia binario.
 +
Le classi utilizzate per implementare la classe qui riportata sono:
 +
* [https://docs.oracle.com/javase/8/docs/api/java/io/File.html File]
 +
* [https://docs.oracle.com/javase/8/docs/api/java/io/FileReader.html FileReader]
 +
* [https://docs.oracle.com/javase/8/docs/api/java/io/InputStreamReader.html  InputStreamReader]
 +
* [https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html BufferedReader]
 +
* [https://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html PrintWriter]
 +
* [https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html RandomAccessFile]
 +
 
 +
<syntaxhighlight lang="java" line>
 +
import java.io.BufferedReader;
 +
import java.io.File;
 +
import java.io.FileNotFoundException;
 +
import java.io.FileReader;
 +
import java.io.IOException;
 +
import java.io.InputStreamReader;
 +
import java.io.PrintWriter;
 +
import java.io.RandomAccessFile;
 +
 
 +
public class GestioneFile {
 +
 
 +
String textFileName = "testo.txt";
 +
String binaryFileName = "binario.dat";
 +
 +
public void printFile() {
 +
try {
 +
PrintWriter output = new PrintWriter(textFileName);
 +
output.print("Stampa su file di una stringa di testo");
 +
output.close();
 +
} catch (FileNotFoundException e) {
 +
// Blocco di gestione delle eccezioni
 +
e.printStackTrace();
 +
}
 +
}
 +
 +
public String readFromFile() {
 +
String line = null;
 +
try {
 +
// Lettura di input da console
 +
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
 +
line = console.readLine();
 +
System.out.println(line);
 +
 +
// Lettura di input da file
 +
BufferedReader fileReader = new BufferedReader(new FileReader(new File(textFileName)));
 +
// Lettura di un singolo carattere
 +
char c = (char)fileReader.read();
 +
System.out.print(c);
 +
// Lettura di una riga di testo
 +
line = fileReader.readLine();
 +
 +
fileReader.close();
 +
console.close();
 +
 +
 +
} catch (IOException e) {
 +
// Blocco di gestione delle eccezioni
 +
e.printStackTrace();
 +
}
 +
return line;
 +
}
 +
 +
public void writeBinaryFile() {
 +
int[] v = new int[] {1000,2,3,4,5,6,7,8,9,10};
 +
try {
 +
RandomAccessFile binaryFile = new RandomAccessFile(new File(binaryFileName), "rw");
 +
for (int i = 0; i < 10; i++) {
 +
binaryFile.writeInt(v[i]);
 +
}
 +
binaryFile.close();
 +
} catch (Exception e) {
 +
// Blocco di gestione delle eccezioni
 +
e.printStackTrace();
 +
}
 +
}
 +
 +
public void readBinaryFile() {
 +
try {
 +
File file = new File(binaryFileName);
 +
RandomAccessFile binaryFile = new RandomAccessFile(file, "r");
 +
 +
int numIntegers = (int)file.length()/4;
 +
int[] v = new int[numIntegers];
 +
 +
for (int i = 0; i < numIntegers; i++) {
 +
v[i] = binaryFile.readInt();
 +
}
 +
 +
binaryFile.close();
 +
 +
// Stampa il vettore acquisito
 +
for (int i = 0; i < numIntegers; i++) {
 +
System.out.print(v[i] + " ");
 +
}
 +
} catch (Exception e) {
 +
// Blocco di gestione delle eccezioni
 +
e.printStackTrace();
 +
}
 +
}
 +
}
 +
</syntaxhighlight>
  
== Apertura e Chiusura di un file ==
+
Di seguito la classe Principale che implementa il metodo main nel quale vengono richiamate le funzioni della classe Gestione File precedentemente introdotta.
L'operazione di apertura di un file, senza la quale non sarebbe possibile effettuare le altre operazioni, consente di accedervi e di associare ad esso uno specifico riferimento (o handle).
+
<syntaxhighlight lang="java" line>
Per poter utilizzare un file, quindi aprirlo, si utilizza la funzione ''fopen'' la cui sintassi è la seguente:
+
public class Principale {
<div align="center">
+
<code>''fileID'' = fopen(''filename'',''permission'')</code>
+
public static void main(String[] args) {
</div>
+
GestioneFile f = new GestioneFile();
dove ''fileID'' è il riferimento al file restituito dalla funzione ''fopen'' (-1 se l'operazione di apertura non va a buon fine), ''filename'' è la stringa contenente il nome (percorso) del file da leggere/scrivere, mentre ''permission'' permette di definire la modalità di accesso al file. Tutte le specifiche si trovano nella documentazione della funzione [https://it.mathworks.com/help/matlab/ref/fopen.html fopen]; di seguito sono riportate le modalità più comuni di accesso al file.
+
f.printFile();
 +
 +
String l = f.readFromFile();
 +
System.out.println(l);
 +
 +
f.writeBinaryFile();
 +
f.readBinaryFile();
 +
}
 +
}
 +
</syntaxhighlight>

Versione attuale delle 15:14, 5 mag 2018

Vitoantonio Bevilacqua vitoantonio.bevilacqua@poliba.it

Antonio Brunetti antonio.brunetti@poliba.it

Gianpaolo Francesco Trotta gianpaolofrancesco.trotta@poliba.it

Pagina in lavorazione

Introduzione

Java fornisce classi e metodi per scrivere e leggere dati da files; le tipologie di files che si possono trovare sono sostanzialmente due:

  • file di testo;
  • file binari.

Grazie alle classi fornite da Java, la gestione dell'input/output da file è indipendente dalla piattaforma su cui il programma verrà eseguito; inoltre, le operazioni di I/O sono basate sul concetto di flusso (stream), ovvero una sequenza ordinata di dati che ha una sorgente e una destinazione.

Per leggere dati da una sorgente bisogna collegarla a uno stream, dove leggere le informazioni in modo ordinato. Analogamente, per scrivere dati su una destinazione, bisogna collegarla a uno stream in cui inserire i dati in modo sequenziale. All’inizio di queste operazioni occorre aprire lo stream e alla fine occorre chiuderlo.


Lettura e scrittura di caratteri con file di testo

Introduzione alle classi e ai metodi per la lettura e scrittura di caratteri o byte su file.

Di seguito sono riportati due esempi che implementano I/O con i file.

Lettura da file di testo

  1. import java.io.*;
  2.  
  3. public class Principale {
  4.  
  5. 	public static void main(String[] args) {
  6. 		new Principale().run();
  7. 	}
  8.  
  9. 	public void run() {
  10. 		/* Per la lettura e scrittura di file,
  11. 		 * si utilizzano le classi di java.io:
  12. 		 * - FileReader (FileInputStream)
  13. 		 * - FileWriter (FileOutputStream)
  14. 		 * che permettono di gestire l'I/O di caratteri o bytes
  15. 		 */
  16.  
  17. 		FileReader file;
  18. 		try {
  19. 			// Lettura di file di testo con due letture successive
  20. 			file = new FileReader("dati.txt");
  21. 			int carattere = file.read();
  22. 			int carattere2 = file.read();
  23.  
  24. 			System.out.println("Il codice del carattere vale: " + carattere);
  25. 			System.out.println("Il codice del carattere vale: " + carattere2);
  26. 			file.close();
  27.  
  28. 			// Lettura di tutto il contenuto del file di testo con ciclo while
  29. 			file = new FileReader("dati.txt");
  30. 			// Letura di tutti i caratteri all'interno di un file di testo
  31. 			int next = file.read();
  32. 			while(next != -1) {
  33. 				char nextc = (char) next;
  34.                 System.out.print(nextc); // stampa il carattere
  35.                 next = file.read(); // legge il prossimo carattere
  36. 			}
  37. 			file.close();
  38.  
  39. 		} catch (IOException e) {
  40. 			// TODO Auto-generated catch block
  41. 			e.printStackTrace();
  42. 		}
  43. 	}
  44. }

Scrittura su file di testo

  1. import java.io.FileWriter;
  2. import java.io.IOException;
  3. import java.util.Scanner;
  4.  
  5. public class Principale2 {
  6.  
  7. 	public static void main(String[] args) {
  8. 		// TODO Auto-generated method stub
  9. 		new Principale2().run();
  10. 	}
  11.  
  12. 	public void run() {
  13. 		/* Per la lettura e scrittura di file,
  14. 		 * si utilizzano le classi di java.io:
  15. 		 * - FileReader (FileInputStream)
  16. 		 * - FileWriter (FileOutputStream)
  17. 		 * che permettono di gestire l'I/O di caratteri o bytes
  18. 		 */
  19.  
  20. 		FileWriter file;
  21. 		Scanner s = new Scanner(System.in);
  22. 		try {
  23. 			// Scrittura su file di testo di numeri acquisiti da tastiera
  24. 			file = new FileWriter("dati_output.txt");
  25.  
  26. 			String num = s.nextLine();
  27. 			while(!num.equals("-1")) {
  28. 				file.write(num + " ");
  29. 				num = s.nextLine();
  30. 			}
  31.  
  32. 			file.close();
  33.  
  34. 			System.out.println("Dati scritti e file chiuso");
  35.  
  36. 		} catch (IOException e) {
  37. 			e.printStackTrace();
  38. 		}
  39. 	}
  40. }

Scrittura e lettura con file binari

  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.util.Scanner;
  5.  
  6. public class Principale3 {
  7.  
  8. 	public static void main(String[] args) {
  9. 		// TODO Auto-generated method stub
  10. 		new Principale3().run();
  11. 	}
  12.  
  13. 	public void run() {
  14. 		/* Per la lettura e scrittura di file,
  15. 		 * si utilizzano le classi di java.io:
  16. 		 * - FileReader (FileInputStream)
  17. 		 * - FileWriter (FileOutputStream)
  18. 		 * che permettono di gestire l'I/O di caratteri o bytes
  19. 		 */
  20.  
  21. 		FileOutputStream fileOutput;
  22. 		Scanner s = new Scanner(System.in);
  23. 		try {
  24. 			// Scrittura su file binario di numeri acquisiti da tastiera
  25. 			fileOutput = new FileOutputStream("dati_output.dat");
  26.  
  27. 			int num = s.nextInt();
  28. 			while(num != -1) {
  29. 				fileOutput.write(num);
  30. 				num = s.nextInt();
  31. 			}
  32.  
  33. 			fileOutput.close();
  34. 			System.out.println("Dati scritti e file chiuso");
  35.  
  36. 			FileInputStream fileInput;
  37. 			fileInput = new FileInputStream("dati_output.dat");
  38.  
  39. 			int numR = fileInput.read();
  40. 			while (numR != -1) {
  41. 				System.out.println("Il numero letto vale: " + numR);
  42. 				numR = fileInput.read();
  43. 			}
  44. 			fileInput.close();
  45. 			System.out.println("Raggiunta fine del file");
  46.  
  47. 		} catch (IOException e) {
  48. 			// TODO Auto-generated catch block
  49. 			e.printStackTrace();
  50. 		}
  51. 	}
  52. }

Lettura e scrittura bufferizzata

Per la gestione dell'input/output con i file, è possibile utilizzare metodi di classi che implementano funzionalità di I/O più avanzate. Nello specifico, qui verranno utilizzate le classi BufferedReader e BufferedWriter che, a differenza delle classi precedenti (FileReader e FileWriter), riducono il numero di accessi a file e consentono di scrivere/leggere dati più complessi dei singoli bytes utilizzando dei buffer per memorizzare temporaneamente i dati da scrivere.

Di seguito ci sono 2 esempi che implementano la lettura e la scrittura bufferizzata sui file di testo.

Scrittura bufferizzata su file di testo

  1. import java.io.BufferedWriter;
  2. import java.io.FileWriter;
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5. import java.util.Scanner;
  6.  
  7. public class Principale4 {
  8.  
  9. 	public static void main(String[] args) {
  10. 		// TODO Auto-generated method stub
  11. 		new Principale4().run();
  12. 	}
  13.  
  14. 	public void run() {
  15. 		/* Le classi FileReader e FileWriter forniscono i metodi di base 
  16. 		 * per leggere o scrivere caratteri su file. 
  17. 		 * Non è conveniente usarle direttamente nei programmi perché 
  18. 		 * non permettono di leggere/scrivere direttamente 
  19. 		 * dati più complessi come stringhe e numeri.
  20. 		 */
  21.  
  22. 		/* Per ovviare a questo problema di possono utilizzare classi che
  23. 		 * implementano funzionalità di I/O più avanzate.
  24. 		 * - BufferedReader
  25. 		 * - BufferedWriter 
  26. 		 * usano un buffer per memorizzare temporaneamente i caratteri da leggere/scrivere, 
  27. 		 * in modo da ridurre il numero di accessi al file;
  28. 		 * 
  29. 		 * - PrintWriter 
  30. 		 * fornisce i metodi print e println, che permettono di scrivere qualunque dato Java, 
  31. 		 * convertendolo automaticamente in stringa.
  32. 		 */
  33.  
  34. 		// Scrittura di dati su file
  35. 		FileWriter fileOutput;
  36. 		BufferedWriter bufferWriter;
  37. 		PrintWriter printWriter;
  38. 		Scanner s = new Scanner(System.in);
  39. 		try {
  40. 			// Scrittura su file testo di numeri acquisiti da tastiera
  41. 			fileOutput = new FileWriter("dati_output2.txt");
  42. 			bufferWriter = new BufferedWriter(fileOutput);
  43. 			printWriter = new PrintWriter(bufferWriter);
  44.  
  45. 			int num = s.nextInt();
  46. 			while(num != -1) {
  47. 				printWriter.println(num);
  48. 				num = s.nextInt();
  49. 			}
  50.  
  51. 			System.out.println("Dati scritti");
  52.  
  53. 			// Proviamo con un vettore
  54. 			int[] v = {1, 2, 3, 4, 5};
  55. 			// L'istruzione seguente non stampa gli elementi del vettore, ma solo il valore utilizzato come reference
  56. 			printWriter.print(v);
  57. 			/* Il seguente ciclo for permette la stampa su file di testo degli elementi contenuti nel vettore
  58. 			 * for (int i = 0; i < 5; i++) {
  59. 			 * 		printWriter.print(v[i] + " ");
  60. 			 * 	}
  61. 			 */
  62. 			System.out.println("Vettore scritto");
  63. 			printWriter.close();
  64.  
  65. 		} catch (IOException e) {
  66. 			// TODO Auto-generated catch block
  67. 			e.printStackTrace();
  68. 		}
  69. 	}
  70. }

Lettura bufferizzata da file di testo

  1. import java.io.BufferedReader;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4.  
  5. public class Principale5 {
  6.  
  7. 	public static void main(String[] args) {
  8. 		// TODO Auto-generated method stub
  9. 		new Principale5().run();
  10. 	}
  11.  
  12. 	public void run() {
  13. 		/* Le classi FileReader e FileWriter forniscono i metodi basici 
  14. 		 * per leggere o scrivere caratteri su file. 
  15. 		 * Non è conveniente usarle direttamente nei programmi perché 
  16. 		 * non permettono di leggere/scrivere direttamente 
  17. 		 * dati più complessi come stringhe e numeri.
  18. 		 */
  19.  
  20. 		/* Per ovviare a questo problema di possono utilizzare classi che
  21. 		 * implementano funzionalità di I/O più avanzate.
  22. 		 * - BufferedReader
  23. 		 * - BufferedWriter 
  24. 		 * usano un buffer per memorizzare temporaneamente i caratteri da leggere/scrivere, 
  25. 		 * in modo da ridurre il numero di accessi al file;
  26. 		 * 
  27. 		 * - PrintWriter 
  28. 		 * fornisce i metodi print e println, che permettono di scrivere qualunque dato Java, 
  29. 		 * convertendolo automaticamente in stringa.
  30. 		 */
  31.  
  32. 		// Scrittura di dati da file
  33. 		FileReader fileInput;
  34. 		BufferedReader bufferReader;
  35. 		int i, num;
  36. 		try {
  37. 			// Lettura da file di testo di numeri
  38. 			fileInput = new FileReader("dati_output2.txt");
  39. 			bufferReader = new BufferedReader(fileInput);
  40.  
  41. 			String s = bufferReader.readLine();
  42. 			while (s != null) {
  43. 				System.out.println(s);
  44. 				s = bufferReader.readLine();
  45. 			}
  46.  
  47. 			for (i = 0; i < 10; i++) {
  48. 				// L'istruzione seguente permette di convertire in intero una stringa...
  49. 				// funzioni analoghe esistono per gli altri tipi di valori
  50. 				num = Integer.parseInt(bufferReader.readLine());
  51. 				System.out.println(num);
  52. 			}
  53.  
  54. 			bufferReader.close();
  55. 			fileInput.close();
  56.  
  57. 		} catch (IOException e) {
  58. 			// TODO Auto-generated catch block
  59. 			e.printStackTrace();
  60. 		}
  61. 	}
  62. }

File ad accesso casuale

La classe RandomAccessFile permette di accedere in lettura e scrittura a file ad accesso casuale, ovvero permette di muoversi all'interno del file in qualunque posizione si desideri in maniera non sequenziale.

Di seguito si trova un esempio che mostra come è possibile utilizzare questa classe.

  1. import java.io.IOException;
  2. import java.io.RandomAccessFile;
  3.  
  4. public class Principale6 {
  5.  
  6. 	public static void main(String[] args) {
  7. 		new Principale6().run();
  8. 	}
  9.  
  10. 	public void run() {
  11. 		/* La classe RandomAccessFile permette di istanziare oggetti
  12. 		 * in grado di gestire l'accesso casuale ai file.
  13. 		 * Un oggetto di tipo RandomAccessFile può essere istanziato specificando il percorso del file (o in oggetto di tipo File)
  14. 		 * e la modalità di apertura.
  15. 		 * In questo contesto, le principali modalità di apertura dei file sono:
  16. 		 *  - r: apertura in sola modalità lettura;
  17. 		 *  - rw: apertura in modalità lettura e scrittura. In questo caso, se il file non esiste, esso viene creato.
  18. 		 */
  19.  
  20. 		RandomAccessFile raf;
  21. 		int i, num;
  22. 		try {
  23. 			// Scrittura su file binario di numeri acquisiti da tastiera
  24. 			raf = new RandomAccessFile("datiRandom.dat", "rw");
  25. 			int[] v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  26.  
  27. 			for (i = 0; i < 10; i++) {
  28. 				// writeInt scrive un numero intero sul file
  29. 				raf.writeInt(v[i]);
  30. 			}
  31.  
  32. 			raf.close();
  33.  
  34. 			raf = new RandomAccessFile("datiRandom.dat", "r");
  35. 			System.out.println("Il file è grande: " + raf.length() + "bytes");
  36. 			int first, last;
  37.  
  38. 			// readInt legge un numero intero dal file
  39. 			first = raf.readInt();
  40.  
  41. 			// seek permette di muoversi all'interno del file
  42. 			raf.seek(raf.length() - 4);
  43.  
  44.  
  45. 			last = raf.readInt();
  46. 			raf.close();
  47.  
  48. 			System.out.println("Il primo numero vale: " + first);
  49. 			System.out.println("L'ultimo numero vale: " + last);
  50.  
  51. 		} catch (IOException e) {
  52. 			// TODO Auto-generated catch block
  53. 			e.printStackTrace();
  54. 		}
  55. 	}
  56. }

Lettura e Scrittura su File

Di seguito è riportato un semplice esempio per la gestione dell'input/output da file, sia di testo, sia binario. Le classi utilizzate per implementare la classe qui riportata sono:

  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileReader;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.io.PrintWriter;
  8. import java.io.RandomAccessFile;
  9.  
  10. public class GestioneFile {
  11.  
  12. 	String textFileName = "testo.txt";
  13. 	String binaryFileName = "binario.dat";
  14.  
  15. 	public void printFile() {
  16. 		try {
  17. 			PrintWriter output = new PrintWriter(textFileName);
  18. 			output.print("Stampa su file di una stringa di testo");
  19. 			output.close();
  20. 		} catch (FileNotFoundException e) {
  21. 			// Blocco di gestione delle eccezioni
  22. 			e.printStackTrace();
  23. 		}
  24. 	}
  25.  
  26. 	public String readFromFile() {	
  27. 		String line = null;
  28. 		try {
  29. 			// Lettura di input da console
  30. 			BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
  31. 			line = console.readLine();
  32. 			System.out.println(line);
  33.  
  34. 			// Lettura di input da file
  35. 			BufferedReader fileReader = new BufferedReader(new FileReader(new File(textFileName)));
  36. 			// Lettura di un singolo carattere
  37. 			char c = (char)fileReader.read();
  38. 			System.out.print(c);
  39. 			// Lettura di una riga di testo
  40. 			line = fileReader.readLine();	
  41.  
  42. 			fileReader.close();
  43. 			console.close();
  44.  
  45.  
  46. 		} catch (IOException e) {
  47. 			// Blocco di gestione delle eccezioni
  48. 			e.printStackTrace();
  49. 		}
  50. 		return line;
  51. 	}
  52.  
  53. 	public void writeBinaryFile() {
  54. 		int[] v = new int[] {1000,2,3,4,5,6,7,8,9,10};
  55. 		try {
  56. 			RandomAccessFile binaryFile = new RandomAccessFile(new File(binaryFileName), "rw");
  57. 			for (int i = 0; i < 10; i++) {
  58. 				binaryFile.writeInt(v[i]);
  59. 			}
  60. 			binaryFile.close();
  61. 		} catch (Exception e) {
  62. 			// Blocco di gestione delle eccezioni
  63. 			e.printStackTrace();
  64. 		}
  65. 	}
  66.  
  67. 	public void readBinaryFile() {
  68. 		try {
  69. 			File file = new File(binaryFileName);
  70. 			RandomAccessFile binaryFile = new RandomAccessFile(file, "r");
  71.  
  72. 			int numIntegers = (int)file.length()/4;
  73. 			int[] v = new int[numIntegers];
  74.  
  75. 			for (int i = 0; i < numIntegers; i++) {
  76. 				v[i] = binaryFile.readInt();
  77. 			}
  78.  
  79. 			binaryFile.close();
  80.  
  81. 			// Stampa il vettore acquisito
  82. 			for (int i = 0; i < numIntegers; i++) {
  83. 				System.out.print(v[i] + " ");
  84. 			}
  85. 		} catch (Exception e) {
  86. 			// Blocco di gestione delle eccezioni
  87. 			e.printStackTrace();
  88. 		}
  89. 	}
  90. }

Di seguito la classe Principale che implementa il metodo main nel quale vengono richiamate le funzioni della classe Gestione File precedentemente introdotta.

  1. public class Principale {
  2.  
  3. 	public static void main(String[] args) { 
  4. 		GestioneFile f = new GestioneFile();
  5. 		f.printFile();
  6.  
  7. 		String l = f.readFromFile();
  8. 		System.out.println(l);
  9.  
  10. 		f.writeBinaryFile();
  11. 		f.readBinaryFile();
  12. 	}
  13. }