Archivos

Correspondencia en Python —>

Con java, como con cualquier otro lenguaje de programación, podemos crear archivos, eliminarlos, leerlos o escribir en ellos.

Podemos manipular archivos de texto con extensión «.txt» o archivos binarios (que pueden contener cualquier otro tipo de información).

Leer archivos .txt

Aunque existen varias formas de hacerlo, vamos a ver como funciona la lectura completa de un archivo .txt y que el contenido del archivo se almacene en una variable String.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class Prueba3 {

    public static void main(String[] args) {
        Path fichero = Path.of("Textos/mi_archivo.txt");
            try{
                String texto= Files.readString(fichero);
                System.out.println(texto);
            }
            catch (IOException e){
                System.out.println("No se puede leer el archivo.");
            }
        }
}
Posible resultado:

Este archivo de texto,
está escrito a modo de ejemplo.
Solo tiene 3 líneas.

En primer lugar observamos que se han importado a nuestro código varias clases.

Lo otro importante (en este caso) es definir la ruta del archivo como un objeto de la clase Path. Este ruta partirá de la raíz de nuestro proyecto. Aquí hemos creado una carpeta llamada Textos dentro de la cual se encuentra nuestro archivo .txt

Después hemos creado un bloque try /cath, que se va a encargar de intentar leer el contenido de dicho archivo con el método Files.readString(objeto Path)

Si la lectura del fichero es correcta, su contenido se asigna con este método a la variable String que hemos definido.

Si no es posible localizar o leer el contenido del archivo, se ejecuta lo que se indica en la orden cath

leer archivo línea por línea

En este caso vamos a leer el contenido de un archivo línea por línea.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Prueba3 {

    public static void main(String[] args) {
        int contador=0;
        try{
            BufferedReader lector= new BufferedReader(new FileReader("Textos/mi_archivo.txt"));
            String linea;
            while ((linea= lector.readLine()) !=null){
                contador+=1;
                System.out.println(contador+" "+linea);
            }
        }
        catch (IOException e)
        {
                System.out.println("No se puede leer el archivo.");
            }
        }
}
Posible resultado:

1 Este archivo de texto,
2 está escrito a modo de ejemplo.
3 Solo tiene 3 líneas.

Vemos que han variado las clases que se van a importar.

La primera clase importante es BufferedReader. Hemos creado un objeto de esta clase. Dicho objeto va a actuar como un buffer de entrada donde se guardará en un principio todo el contenido del archivo de texto.

La otra clase es FileReader Esta clase es la que se encarga de leer el contenido del archivo .txt

La clase readLine() se encarga de leer la primera línea disponible en el buffer creado. Mediante un bloque while, comprobamos que la línea no esté vacía, en cuyo caso el contenido de readLine( ) sería null.

La lectura de la línea queda almacenado en la variable que hemos creado de tipo String. También hemos creado un contador que nos vaya contando y numerando las línea

Leer archivo carácter por carácter

Un archivo también puede ser leído carácter por carácter. En el siguiente código leeremos el archivo de esta manera e iremos formando cadenas de 10 caracteres.

import java.io.FileReader;
import java.io.IOException;

public class Prueba3 {


    public static void main(String[] args) {
        String cadena="";

        try{
            FileReader lector=new FileReader("Textos/mi_archivo.txt");
            int caracter;
            int contador=0;
            int contador_cadenas=1;

            while ((caracter= lector.read()) !=-1){
                cadena=(cadena+(char) caracter);
                contador+=1;
                if (contador==10){
                    System.out.println("Cadena "+contador_cadenas+": "+cadena);
                    contador=0;
                    cadena="";
                    contador_cadenas+=1;
                }
            }
            System.out.println("Cadena "+contador_cadenas+": "+cadena);
        }

        catch (IOException e)
        {
                System.out.println("No se puede leer el archivo.");
            }
        }
}

La instrucción FileReader lector=new FileReader(archivo) nos facilita el buffer desde el cual se irán obteniendo los caracteres a demanda. Al objeto de lectura creado en este caso le damos el nombre de lector.

El método lector.read( ) es quien le solicita al buffer que le de el siguiente caracter que tenga almacenado. Este caracter lo vamos almacenando en el objeto String al que hemos llamado cadena. Cuando llevamos 10 caracteres obtenidos, imprimimos la cadena y reiniciamos los valores para obtener otra cadena.

Debemos de tener en cuenta que el caracter «/n» salto de línea se cuenta como uno más. Por eso veremos que hay cadenas que están escritas en dos líneas.

Resultado:

Cadena 1: Este archi
Cadena 2: vo de text
Cadena 3: o,
está es
Cadena 4: crito a mo
Cadena 5: do de ejem
Cadena 6: plo.
Solo 
Cadena 7: tiene 3 lí
Cadena 8: neas.

Creación y escritura en archivos.

Vemos a continuación un ejemplo de código que crea un archivo .txt en caso de que no exista. En el caso que mostramos debemos de tener cuidado, ya que si el archivo existe, lo sobreescribe.

A continuación escribirá en él dos cadenas String.

import java.io.FileWriter;
import java.io.IOException;

public class Prueba3 {
    public static void main(String[] args) {

        String texto_1 = "Me gusta programar en Java.\n";
        String texto_2 = "Me divierte mucho y aprendo.\n";

        try (FileWriter fichero = new FileWriter("Textos/mi_archivo_3.txt", false)){

            fichero.write(texto_1);
            fichero.write(texto_2);

        }
        catch (IOException e) {
            System.out.println("Error al escribir el archivo: " + e.getMessage());
        }
    }
}

En primer lugar creamos un objeto FileWriter, donde podremos añadir nuestros String

Prestamos especial atención al parámetro «false» añadido al objeto cuando lo creamos. El valor de este parámetro (false) indica que se va a sobreescribir un fichero anterior si ya existe con el mismo nombre.

Muy importante también es el lugar que ocupa la creación del objeto en referencia a la instrucción «try». Estamos creando el fichero antes del bloque de código (antes de las llaves), pero justo después de la palabra «try». Y además lo encerramos entre paréntesis. Esto dará lugar a que el fichero se cierre después de ejecutar el código, en caso contrario quedaría abierto y sin escribir nuestros String en él.

En todos los casos, la ruta del archivo partirá de la carpeta raíz de nuestro proyecto.

Añadir contenido a un archivo.

Si en lugar de darle el valor «false» al parámetro indicado anteriormente le damos valor «true» conseguimos dos cosas:

  • Si el archivo no existe, será creado. A continuación se añadirá el contenido que se se indique.
  • Si el archivo ya existe, el archivo se abre y el contenido que se indique se añadirá a continuación del contenido que ya tenía el archivo anteriormente.

Archivos JSON

Un tipo particular de archivos que es muy útil, son los archivos con formato
json. Cuando el usuario necesita guardar una información sencilla, los archivos txt pueden ser suficientes. En cambio cuando se debe de guardar una información más compleja (un ArrayList, objetos de una clase, un HashSet, un ArrayList de HashMap…) entonces podemos acudir a los archivos json, que nos facilitan mucho la tarea.

La gran ventaja de estos archivos, es que las estructuras de datos que guardemos en ellos, serán recuperadas y reutilizadas en nuestro código de una forma muy sencilla.

Otra ventaja más es que pueden ser utilizados en otros lenguajes de programación, o aplicaciones que los acepten. Su uso nos puede facilitar la vida en mucho de los programas que vayamos a crear.

Sin embargo Java no tiene una librería propia que maneje este tipo de archivos. Existen varias de ellas, pero todas requieren su previa importación. Para poderlas incorporar a nuestro proyecto deberemos de seguir las instrucciones que procedan en cada caso para su instalación.

En el siguiente ejemplo, se ha seguido la biblioteca Gson. El código consiste en un elemento base que será un ArrayList de alumnos. Los elementos del ArrayList serán cada uno un HashMap que va a contener información relativa a un alumno. Este ArrayList se guardará al finalizar el programa en un archivo JSON que será recuperado la próxima vez que se ejecute el programa para recuperar a su vez los alumnos ya anotados.

import com.google.gson.Gson;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

public class Prueba3 {
    public static void main(String[] args) {

        File mi_archivo = new File("datos_alumno.json");
        ArrayList<HashMap<String, String>> lista_alumnos = new ArrayList<>();
        HashMap<String, String> alumnos = new HashMap<>();

        String nombre="";
        String apellidos="";
        String edad="";
        String curso="";
        Scanner mi_scanner = new Scanner(System.in);

        Gson gson = new Gson();

        if (mi_archivo.exists()){
            try (FileReader lector = new FileReader(mi_archivo)) {
                lista_alumnos=gson.fromJson(lector, ArrayList.class);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        while (!nombre.equalsIgnoreCase("SALIR")){
            System.out.print("Nombre alumno: ");
            nombre=mi_scanner.nextLine();
            if (!nombre.equalsIgnoreCase("SALIR")){
                alumnos.put("Nombre", nombre );
                System.out.print("Apellidos: ");
                apellidos=mi_scanner.nextLine();
                alumnos.put("Apellidos", apellidos);
                System.out.print("Edad: ");
                edad=mi_scanner.nextLine();
                alumnos.put("Edad", edad);
                System.out.print("Curso: ");
                curso=mi_scanner.nextLine();
                alumnos.put("Curso", curso);

                lista_alumnos.add(new HashMap<>(alumnos));
                alumnos.clear();
            }
        }

        try(FileWriter escritor = new FileWriter(mi_archivo)){
            gson.toJson(lista_alumnos, escritor);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Al ejecutar el código se nos va pidiendo datos de cada alumno. Estos datos se guardarán en el ArrayList que posteriormente será guardado en el archivo JSON para recuperarlo en otra ejecución del código posterior.

  • En primer lugar hemos dado nombre a nuestro archivo: File mi_archivo = new File(«datos_alumno.json»);
  • Con la siguiente instrucción indicamos que vamos a crear un ArrayList que va a contener HashMap como elementos.
    ArrayList<HashMap<String, String>> lista_alumnos = new ArrayList<>();
  • Gson gson = new Gson(); Aquí estamos creando un objeto Gson. Hemos elegido la clase Gson, que hemos tenido que crear en nuestro proyecto Java como una clase externa, ya que no la tiene incluida como nativa por defecto. El procedimiento para crear la clase externa que gestione JSON es diferente según el paquete externo que vayamos a utilizar y según el IDE usado.
  • Con el siguiente bloque comprobamos si existe nuestro archivo JSON ya en nuestro proyecto. Si ya existe, lo abrimos para lectura y cargamos su contenido en el ArrayList.
    lista_alumnos=gson.fromJson(lector, ArrayList.class);
  • A continuación pedimos datos para un nuevo alumno que se creará en un HashMap. Atención aquí a la instrucción:
    (!nombre.equalsIgnoreCase(«SALIR»))
    Sería totalmente erróneo poner: while (nombre!=»SALIR») ya que para comparar si dos String son iguales, debemos de utilizar la instrucción anterior. No vale la comparación habitual para datos tipo «int» o cualquier otro, sino que tenemos que utilizar los métodos que tiene la clase String para comparar. Esta instrucción nos permite seguir introduciendo alumnos hasta que entremos la palabra «salir». Cada nuevo alumno es añadido al ArrayList y continuación el HashMap queda borrado para otro.
  • Ya solo nos queda al salir del programa, escribir en el archivo JSON el contenido del ArrayList para una nueva ejecución posterior del código, cuando será recuperado.
    (FileWriter escritor = new FileWriter(mi_archivo) abre el archivo JSON para escibir en él.
    gson.toJson(lista_alumnos, escritor); Escribe en el archivo el contenido del ArrayList.

A continuación veremos un ejemplo de código que lee y escribe en un archivo JSON un ArrayList, que va a contener objetos de una determinada clase.

En realidad un archivo JSON lo que almacena es un ArrayList de HahMap, que es lo que luego nos va a facilitar. Por lo tanto, si lo que queremos guardar son objetos de clases, debemos de indicar al código que lo que hay dentro del ArrayList no son HashMap sino objetos.

En primer lugar tenemos el código de la clase:

import java.util.ArrayList;

public class Alumno {
    public static int contador ;
    private String nombre;
    private String apellidos;
    private String edad;
    private String curso;
    private String registro;

    public Alumno(String nombre, String apellidos, String edad, String curso) {
        this.nombre = nombre;
        this.apellidos=apellidos;
        this.edad = edad;
        this.curso= curso;
        contador+=1;
        this.registro=String.format("%05d", contador);
    }
    public static void imprimir_todos(ArrayList listado){

        if (!listado.isEmpty()){
            System.out.println("Lista alumnos actualizada:\n");
            for (int k=0; k<listado.size(); k++){
                System.out.println(listado.get(0));
            }
        }
    }

    @Override
    public String toString()
    {
        String cadena=("Registro alumnos: "+registro+"."+"\n"+
                       "Nombre: "+nombre+"."+"\n"+
                       "Apellidos: "+apellidos+"."+"\n"+
                       "Edad: "+edad+"."+"\n"+
                       "Curso: "+curso+"."+"\n");
        return cadena;
    }
}

Esta es una clase sencilla donde hemos añadido un atributo contador que nos servirá para añadir a cada alumno su número de registro.

Hemos añadido un método a través del cual podemos mostrar en pantalla los datos de todos los alumnos que tengamos en ese momento.

A continuación el código que nos va a permitir guardar los objetos de la clase en un fichero JSON:

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;

public class Prueba3 {
    public static void main(String[] args) {

        File mi_archivo = new File("alumnos_clase.json");
        ArrayList<Alumno> lista_alumnos = new ArrayList<>();

        String nombre="";
        String apellidos="";
        String edad="";
        String curso="";
        Scanner mi_scanner = new Scanner(System.in);

        Gson gson = new Gson();

        if (mi_archivo.exists()){
            try (FileReader lector = new FileReader(mi_archivo)) {
                Type tipoLista = new TypeToken<ArrayList<Alumno>>() {}.getType();
                lista_alumnos=gson.fromJson(lector, tipoLista);
                Alumno.contador=lista_alumnos.size();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        Alumno.imprimir_todos(lista_alumnos);

        while (!nombre.equalsIgnoreCase("SALIR")){
            System.out.print("(Para salir nombre=salir). Nombre alumno: ");
            nombre=mi_scanner.nextLine();
            if (!nombre.equalsIgnoreCase("SALIR")){
                System.out.print("Apellidos: ");
                apellidos=mi_scanner.nextLine();
                System.out.print("Edad: ");
                edad=mi_scanner.nextLine();
                System.out.print("Curso: ");
                curso=mi_scanner.nextLine();

                lista_alumnos.add(new Alumno(nombre, apellidos,edad,curso));
            }
        }

        try(FileWriter escritor = new FileWriter(mi_archivo)){
            gson.toJson(lista_alumnos, escritor);
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        Alumno.imprimir_todos(lista_alumnos);
    }
}

Este código es muy parecido al mostrado en el ejercicio anterior con las siguientes instrucciones en particular:

  • ArrayList lista_alumnos = new ArrayList<>(); Creamos el ArrayList cuyo contenido será la lista de alumnos existentes.
  • Type tipoLista = new TypeToken<ArrayList<Alumno>>() {}.getType(); Esta es la instrucción más importante. Nos crea un objeto ArrayList cuyo contenido va a ser objetos de la clase Alumno.
  • lista_alumnos=gson.fromJson(lector, tipoLista); Nos lee el archivo JSON y guarda en lista_alumnos su contenido.
  • gson.toJson(lista_alumnos, escritor); Escribe en el archivo JSON el contenido del ArrayList.
Posible resultado en una primera ejecución del código:

(Para salir nombre=salir). Nombre alumno: Eduardo
Apellidos: Pizarro Pérez
Edad: 20
Curso: 2
(Para salir nombre=salir). Nombre alumno: Javier
Apellidos: García Picapiedra
Edad: 21
Curso: 2
(Para salir nombre=salir). Nombre alumno: Elisa
Apellidos: Ruiz Pino
Edad: 19
Curso: 1
(Para salir nombre=salir). Nombre alumno: salir
Lista alumnos actualizada:

Registro alumnos: 00001.
Nombre: Eduardo.
Apellidos: Pizarro Pérez.
Edad: 20.
Curso: 2.

Registro alumnos: 00002.
Nombre: Javier.
Apellidos: García Picapiedra.
Edad: 21.
Curso: 2.

Registro alumnos: 00003.
Nombre: Elisa.
Apellidos: Ruiz Pino.
Edad: 19.
Curso: 1.
Posible resultado en una segunda ejecución del código:

Lista alumnos actualizada:

Registro alumnos: 00001.
Nombre: Eduardo.
Apellidos: Pizarro Pérez.
Edad: 20.
Curso: 2.

Registro alumnos: 00002.
Nombre: Javier.
Apellidos: García Picapiedra.
Edad: 21.
Curso: 2.

Registro alumnos: 00003.
Nombre: Elisa.
Apellidos: Ruiz Pino.
Edad: 19.
Curso: 1.

(Para salir nombre=salir). Nombre alumno: Ana
Apellidos: Casillas Oca
Edad: 23
Curso: 2
(Para salir nombre=salir). Nombre alumno: Carlos
Apellidos: Messi Ronaldo
Edad: 22
Curso: 3
(Para salir nombre=salir). Nombre alumno: salir
Lista alumnos actualizada:

Registro alumnos: 00001.
Nombre: Eduardo.
Apellidos: Pizarro Pérez.
Edad: 20.
Curso: 2.

Registro alumnos: 00002.
Nombre: Javier.
Apellidos: García Picapiedra.
Edad: 21.
Curso: 2.

Registro alumnos: 00003.
Nombre: Elisa.
Apellidos: Ruiz Pino.
Edad: 19.
Curso: 1.

Registro alumnos: 00004.
Nombre: Ana.
Apellidos: Casillas Oca.
Edad: 23.
Curso: 2.

Registro alumnos: 00005.
Nombre: Carlos.
Apellidos: Messi Ronaldo.
Edad: 22.
Curso: 3.
InicioComandos JavaBloques de código.
Comentar códigoSystem.out.printScanner (System.in)
Captura de erroresStringDatos Numéricos
Elementos aleatoriosDatos Fecha/horaConstantes
Bucles forBucles whileBloque if
ArraysArrayListswitch case
HashSetHashMapMétodos.
ClasesArchivosEntorno gráfico Swing
JFrame (Ventanas)Componentes básicos.