I File in Java: differenze tra le versioni

Da Bioingegneria Elettronica e Informatica.
(Lettura e scrittura bufferizzata)
(Scrittura bufferizzata su file di testo)
Riga 175: Riga 175:
  
 
=== Scrittura bufferizzata su file di testo ===
 
=== Scrittura bufferizzata su file di testo ===
 +
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 ===
 
=== Lettura bufferizzata da file di testo ===

Versione delle 15:07, 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

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

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