Lettura fino alla fine del file

Nella maggior parte dei casi, un file va letto fino alla fine, e non oltre. In altre parole, vanno letti tutti i suoi caratteri, ma ci si deve fermare quando il file è finito.

Quindi, occorre eseguire fr.read() ripetutamente, fermandosi soltanto quando il valore è -1.

Dal momento che non si sa a priori quanti caratteri contiene un file, occorre un ciclo indefinito (while). Si deve infatti andare avanti fino a che fr.read() non ritorna -1.

Il programma FinePrima.java contiene una prima versione del ciclo di lettura (contiene vari errori che verranno ora evidenziati).

import java.io.*;

class FinePrima {
  public static void main(String args[])
  throws IOException {
    FileReader fr;
    fr=new FileReader("prova.txt");

    int x;
    char c;

    while(x!=-1) {
      x=fr.read();
      c=(char) x;
      System.out.println(c);
    }
  }
}

Il primo errore è che quando viene controllata la condizione x!=-1, la variabile x non è stata inizializzata. Questo è vero, infatti x è stata creata ma non gli è stato assegnato nessun valore quando si arriva a while(x!=-1).

La soluzione è impostare un primo valore diverso da -1, in modo che si entri nel ciclo. Il programma FineSeconda.java non dà l'errore di compilazione, ma presenta ugualmente un problema.

import java.io.*;

class FineSeconda {
  public static void main(String args[])
  throws IOException {
    FileReader fr;
    fr=new FileReader("prova.txt");

    int x=0;
    char c;

    while(x!=-1) {
      x=fr.read();
      c=(char) x;
      System.out.println(c);
    }
  }
}

Questo programma compila e può quindi venire eseguito. L'esecuzione però mostra un piccolo problema: oltre ai caratteri del file, viene alla fine stampato un carattere non riconosciuto in fondo.

Questo è dovuto al fatto che quando il file è finito (ossia l'ultimo carattere è già stato stampato) l'esecuzione di x=fr.read() assegna a x il valore -1. Questo valore indica che il file è già finito, ossia che l'ultimo carattere è già stato letto in precedenza. Quindi, il valore -1 non va convertito in carattere e stampato.

Il programma seguente Fine.java contiene la correzione che evita la stampa di troppo.

import java.io.*;

class Fine {
  public static void main(String args[])
  throws IOException {
    FileReader fr;
    fr=new FileReader("prova.txt");

    int x=0;
    char c;

    while(x!=-1) {
      x=fr.read();
      if(x!=-1) {
        c=(char) x;
        System.out.println(c);
      }
    }
  }
}