Lectura y Escritura de Ficheros en Java

 

Hola a todos, hoy os explicare como podemos manejar las clases FileReader y FileWritter para ficheros de texto en Java.

Las clases FileReader y FileWriter permiten leer y escribir, respectivamente, en un fichero.

Lo primero que debemos hacer es importar estas clases y las que controlan las excepciones.

Después debemos crear un objeto de alguna de estas clases. Se pueden construir con un objeto File, FileDescriptor o un String. Nosotros usaremos este último.

Al crear un objeto de estas clases, deben estar dentro de un try-catch.

Recuerda que debemos controlar las excepciones.

Cuando creamos un objeto, abrimos un stream entre nuestro programa y el exterior, cuando debemos de usarlo debemos cerrar el stream con el método close().

Veamos un ejemplo, de creación de los objetos, también cerramos los streams:

1
2
FileWriter fw=new FileWriter("D:\\fichero1.txt");
FileReader fr=new FileReader("D:\\fichero1.txt");

Como vemos, escribimos la ruta del fichero. Si usas FileWriter y escribes una ruta de fichero que no existe lo crea, para FileReader si que debe existir el fichero, sino lanzara una excepción. Usamos doble barra (\\) por que es un carácter de escape, para poner \.

Ahora vamos a ver como escribir y leer texto en el fichero.

Para escribir, usaremos el método write de FileWriter, este método puede usar como parámetro un String con lo que queremos escribir o un número que se corresponderá un carácter de la tabla ASCII.

Para leer, usaremos el método read de FileReader, este método no tiene parámetros pero devuelve un número que si le hacemos un casting a char este sera legible por nosotros. Esto lo podemos mostrar por pantalla o incluso pasarlo a otro fichero (crear otro objeto). Cuando se termina el fichero, el método read devuelve -1.

Veamos un ejemplo, primero escribiremos en el fichero y luego lo leemos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.*;
//Importamos todas las clases de java.io.<br />public class FicheroTextoApp {
    public static void main(String[] args) {
        try{
            //Abro stream, crea el fichero si no existe
            FileWriter fw=new FileWriter("D:\\fichero1.txt");
            //Escribimos en el fichero un String y un caracter 97 (a)
            fw.write("Esto es una prueb");
            fw.write(97);
            //Cierro el stream
            fw.close();
                //Abro el stream, el fichero debe existir
            FileReader fr=new FileReader("D:\\fichero1.txt");
            //Leemos el fichero y lo mostramos por pantalla
            int valor=fr.read();
            while(valor!=-1){
                System.out.print((char)valor);
                valor=fr.read();
            }
            //Cerramos el stream
            fr.close();
        }catch(IOException e){
            System.out.println("Error E/S: "+e);
        }
    }
}

La idea es abrir un fichero, escribir o leer y cerrar el fichero. No es necesario que hagamos nada para mover el puntero del fichero, cuando leemos un carácter automáticamente el puntero se mueve.

¿Que pasa si escribiera el siguiente código?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.io.*;
//Importamos todas las clases de java.io.
public class FicheroTextoApp {
    public static void main(String[] args) {
        try{
            //Creo los objetos, abro streams
            FileWriter fw=new FileWriter("D:\\fichero1.txt");
            FileReader fr=new FileReader("D:\\fichero1.txt");
            //Escribimos en el fichero un String y un caracter 97 (a)
            fw.write("Esto es una prueb");
            fw.write(97);
            //Leemos el fichero y lo mostramos por pantalla
            int valor=fr.read();
            while(valor!=-1){
                System.out.print((char)valor);
                valor=fr.read();
            }
            //Cerramos el stream
            fw.close();
            fr.close();
        }catch(IOException e){
            System.out.println("Error E/S: "+e);
        }
    }
}

Si ejecutamos el código, no escribirá nada en pantalla pero si escribirá en el fichero, la pregunta es ¿Porque? La respuesta es que  cuando se cierra el stream, es como si pincháramos en guardar de forma gráfica, es decir, que si no cerramos el stream es como si el fichero estuviera vacio. También debemos tener en cuenta que esto se debe a que leemos y modificamos el mismo fichero en el mismo tiempo.

¿Entonces que podemos hacer? Podemos hacer como lo hemos visto antes o podemos usar el métodoflush() de FileWriter que hace que se guarden los cambios. Veamos como queda:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.*;
//Importamos todas las clases de java.io.
public class FicheroTextoApp {
    public static void main(String[] args) {
        try{
            //Creo los objetos, abro streams
            FileWriter fw=new FileWriter("D:\\fichero1.txt");
            FileReader fr=new FileReader("D:\\fichero1.txt");
            //Escribimos en el fichero un String y un caracter 97 (a)
            fw.write("Esto es una prueb");
            fw.write(97);
            //Guardamos los cambios del fichero
            fw.flush();
            //Leemos el fichero y lo mostramos por pantalla
            int valor=fr.read();
            while(valor!=-1){
                System.out.print((char)valor);
                valor=fr.read();
            }
            //Cerramos el stream
            fw.close();
            fr.close();
        }catch(IOException e){
            System.out.println("Error E/S: "+e);
        }
    }
}

Desde java 7 tenemos una mejor forma de abrir y cerrar stream, ahorrándonos trabajo.

Veamos como seria:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.io.*;
//Importamos todas las clases de java.io.
public class FicheroTextoApp {
    public static void main(String[] args) {
        try(FileWriter fw=new FileWriter("D:\\fichero1.txt");
            FileReader fr=new FileReader("D:\\fichero1.txt")){
            //Escribimos en el fichero un String y un caracter 97 (a)
            fw.write("Esto es una prueb");
            fw.write(97);
            //Guardamos los cambios del fichero
            fw.flush();
            //Leemos el fichero y lo mostramos por pantalla
            int valor=fr.read();
            while(valor!=-1){
                System.out.print((char)valor);
                valor=fr.read();
            }
        }catch(IOException e){
            System.out.println("Error E/S: "+e);
        }
    }
}

Como vemos, en el try creamos los objetos que queremos manejar, separados con un ; por objeto, con esta forma los streams se cierran automáticamente.

Por último, si queremos añadir mas texto a un fichero de texto que ya tenga contenido, al construir el objeto de la clase FileWriter añadimos como segundo parámetro un true. Si no lo hacemos, sobrescribiremos el fichero entero al escribir algo nuevo.

Ahora veremos el mismo ejemplo anterior pero usando métodos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.io.*;
//Importamos todas las clases de java.io.
public class FicheroTextoApp {
    public static void main(String[] args) {
        try(FileReader fr=new FileReader("D:\\fichero1.txt");
            FileWriter fw=new FileWriter("D:\\fichero1.txt")){
            escribeFichero(fw);
            //Guardamos los cambios del fichero
            fw.flush();
            leeFichero(fr);
        }catch(IOException e){
            System.out.println("Error E/S: "+e);
        }
    }
    public static void escribeFichero(FileWriter fw) throws IOException{
        //Escribimos en el fichero
        fw.write("Esto es una prueba");
    }
    public static void leeFichero(FileReader fr) throws IOException{
        //Leemos el fichero y lo mostramos por pantalla
        int valor=fr.read();
        while(valor!=-1){
            System.out.print((char)valor);
            valor=fr.read();
        }
    }
}

 

Bibliografia:

http://www.discoduroderoer.es/clases-filereader-y-filewriter-para-ficheros-de-texto-en-java/