miércoles, 13 de febrero de 2019

Java: Leer un fichero TXT y transformarlo en un JSON

Vamos a crear una aplicación que lea el contenido de un fichero .txt y que lo transforme en un fichero con un objeto JSON válido.

Vamos a suponer que tenemos un fichero txt que contiene las preguntas y respuestas de un examen, en este formato:

1. F. Galton orientó sus hallazgos hacia:
A) Una vertiente aplicada.
B) Una vertiente académica.***
C) Una perspectiva educativa.


2. Señale qué característica NO se corresponde con los diseños de investigación ex post facto:
A) La persona que investiga no puede hacer una asignación aleatoria de los sujetos a las condiciones experimentales.***
B) La persona que investiga no puede manipular la variable independiente.
C) La persona que investiga puede seleccionar los sujetos que desea investigar y manipular una o más variables independientes.


3. Señale la afirmación INCORRECTA: El 'censo psicológico' permite:
A) Conocer todas las capacidades intelectuales existentes a nivel universal.
B) Estimar la posición relativa de cualquier individuo en una característica psicológica determinada con respecto a la población de pertenencia, en general.***
C) Comparar a los individuos entre sí, en particular, analizando las diferencias individuales existentes entre ellos.


4. El desarrollo del modelo y objeto de estudio de las diferencias individuales propuesto por F. Galton partió de:
A) Las leyes generales de la mente humana propuestas por W. Wundt.
B) Un modelo biológico de corte darwiniano.***
C) La concepción de A. Binet sobre la inteligencia.


5. El término de 'test mental' acuñado por _____ se desarrolló bajo la concepción de _____ para evaluar procesos _____:
A) Francis Galton / Charles Darwin / evolutivos.
B) Alfred Binet / Francis Galton / mentales complejos.
C) J.Mc.Cattell / Francis Galton / procesos mentales simples y específicos.***


Las respuestas que terminan con "***" son las respuestas correctas a sus respectivas preguntas (en este ejemplo las hemos puesto al azar, no son las respuestas de verdad a las preguntas).

Abrimos el eclipse, creamos un nuevo proyecto Java, y creamos las siguientes clases:

Clase Examen:
package prueba;

import java.util.List;

public class Examen {

 private String idExamen;
 private float valorAcierto;
 private float valorFallo;
 private List<Pregunta> preguntas;
   
 public String getIdExamen() {
  return idExamen;
 }
 public void setIdExamen(String idExamen) {
  this.idExamen = idExamen;
 }
 public float getValorAcierto() {
  return valorAcierto;
 }
 public void setValorAcierto(float valorAcierto) {
  this.valorAcierto = valorAcierto;
 }
 public float getValorFallo() {
  return valorFallo;
 }
 public void setValorFallo(float valorFallo) {
  this.valorFallo = valorFallo;
 }
 public List<Pregunta> getPreguntas() {
  return preguntas;
 }
 public void setPreguntas(List<Pregunta> preguntas) {
  this.preguntas = preguntas;
 }


}

Clase Pregunta:
package prueba;

import java.util.List;

public class Pregunta {

 private String imagen;
 private String enunciado;
 private List<Respuesta> respuestas;

 public String getImagen() {
  return imagen;
 }
 public void setImagen(String imagen) {
  this.imagen = imagen;
 }
 public String getEnunciado() {
  return enunciado;
 }
 public void setEnunciado(String enunciado) {
  this.enunciado = enunciado;
 }
 public List<Respuesta> getRespuestas() {
  return respuestas;
 }
 public void setRespuestas(List<Respuesta> respuestas) {
  this.respuestas = respuestas;
 }


}

Clase Respuesta:
package prueba;

public class Respuesta {

 private String enunciado;
 private boolean respuestaCorrecta;

 public String getEnunciado() {
  return enunciado;
 }
 public void setEnunciado(String enunciado) {
  this.enunciado = enunciado;
 }
 public boolean isRespuestaCorrecta() {
  return respuestaCorrecta;
 }
 public void setRespuestaCorrecta(boolean respuestaCorrecta) {
  this.respuestaCorrecta = respuestaCorrecta;
 }

}


Como se puede ver, la estructura del examen es una clase examen, que tiene una lista de preguntas, y éstas a su vez tienen una lista de respuestas.

Ahora creamos la clase principal, que es la que realizará el trabajo.

Clase Main:
package prueba;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
public class Main {

 public static void main(String[] args) {

  // Creamos el examen.
  Examen examen = new Examen();
  List<Pregunta> listaPreguntas = new ArrayList<Pregunta>();
  Pregunta pregunta = null;
  List<Respuesta> listaRespuestas = null;
  Respuesta respuesta = null;

  examen.setIdExamen("IdExamen");
  examen.setValorAcierto(Float.valueOf("0.25"));
  examen.setValorFallo(Float.valueOf("0.125"));

  // Nos preparamos para leer el fichero.
  FileInputStream fileInputStream = null;
  InputStreamReader inputStreamReader = null;
        BufferedReader buffer = null;
  String linea;

  // En este bloque try creamos el objeto exámen a partir del fichero txt.
  try {
 
   // Abrimos el fichero en formato UTF-8 para que se vean bien los acentos y las ñ.
   fileInputStream = new FileInputStream("C:/Users/X45559SA/Desktop/JunioC.txt");
   inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
   buffer = new BufferedReader(inputStreamReader);
 
         // Leemos las líneas del fichero.
         while ((linea = buffer.readLine()) != null) {
        
          // Comprobamos que la línea no esté vacía.
          if (!linea.isEmpty()) {
        
           // Comprobamos si la línea empieza por un número (es pregunta) o por una letra (es respuesta).
           if (Character.isDigit(linea.charAt(0))) {
         
            // Si es una pregunta, significa que ya ha terminado por completo la pregunta anterior,
            // así que guardamos la lista de respuestas en la pregunta, y la pregunta en la lista de preguntas.
            if (listaRespuestas != null) {
             pregunta.setRespuestas(listaRespuestas);
             listaPreguntas.add(pregunta);
            }
         
            // Y creamos una nueva pregunta y su lista de respuestas.
            pregunta = new Pregunta();
            pregunta.setEnunciado(linea);
            pregunta.setImagen("");
            listaRespuestas = new ArrayList<Respuesta>();
         
           } else {
         
            // Si es una respuesta, creamos una nueva respuesta y la añadimos a la lista de respuestas.
            respuesta = new Respuesta();

            // Si la respuesta termina con tres asteriscos, es porque la respuesta es la buena.
            if (linea.contains("***")) {
             linea = linea.replace("***", "");
             respuesta.setRespuestaCorrecta(true);
            } else {
             respuesta.setRespuestaCorrecta(false);
            }
         
            // Guardamos el enunciado en la respuesta, y la respuesta en la lista de respuestas.
            respuesta.setEnunciado(linea);
            listaRespuestas.add(respuesta);
         
           }
        
          }
        
         }
        
         // Añadimos la última pregunta a la lista de preguntas, que no se guardará en el bucle porque no vuelve a pasar.
         pregunta.setRespuestas(listaRespuestas);
   listaPreguntas.add(pregunta);
        
         // Guardamos la lista de preguntas en el exámen.
         examen.setPreguntas(listaPreguntas);
 
  } catch(Exception e) {
          e.printStackTrace();
     } finally {
    
      // Cerramos el buffer.
      try {
       if ( null != buffer ) {
        buffer.close();
       }
      } catch (Exception e2) {
       e2.printStackTrace();
      }

      // Cerramos el reader.
      try {
       if ( null != inputStreamReader ) {
        inputStreamReader.close();
       }
      } catch (Exception e2) {
       e2.printStackTrace();
      }
    
      // Cerramos el fichero.
      try {
       if ( null != fileInputStream ) {
        fileInputStream.close();
       }
      } catch (Exception e2) {
       e2.printStackTrace();
      }
         
     }

  // A partir de aquí utilizamos el objeto exámen para crear el JSON.
        Gson gson = new Gson();
        Writer writer = null;
       
  try {
 
   // Creamos el fichero JSON utilizando el identificador del exámen como nombre.
   writer = new FileWriter("C:/Users/X45559SA/Desktop/" + examen.getIdExamen() + ".json");
 
   // Creamos el JSON y lo escribimos en el fichero.
         gson.toJson(examen, writer);
 
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
    
      // Cerramos el fichero.
      try {
       if ( null != writer ) {
        writer.flush();
              writer.close();
       }
      } catch (Exception e2) {
       e2.printStackTrace();
      }
        
     }

 }
}

Esta será la clase que realizará todo el trabajo. Como es puede ver, está bastante comentada así que se puede entender bien lo que hace, pero de forma resumida sería:

1. Crear un objeto examen y asignarle los atributos básicos.
2. Se recorre el fichero línea a línea y comprueba (si la línea no está vacía) si la línea es una pregunta o una respuesta y la asigna a su correspondiente ArrayList, que luego será asignado al examen.
3. Con el objeto examen completo, se utiliza la librería Gson para transformar el objeto examen a formato JSON y lo escribimos en otro fichero.

Hay que tener en cuenta que hay que importar al proyecto la librería Gson de Google (como jar externo si no utilizamos Maven). La tenemos en esta url:
https://mvnrepository.com/artifact/com.google.code.gson/gson/2.8.5

Si ejecutamos la aplicación, nos creará un fichero .json de una sola línea. Si copiamos el contenido del fichero y lo pegamos en la url: https://jsonformatter.curiousconcept.com/ podemos formatearlo para que se muestre más legible. Nos quedaría así:


Y eso sería todo.

No hay comentarios:

Publicar un comentario