Ir al contenido principal

Procesando ficheros en JAVA



Con los últimos artículos que estoy escribiendo estoy sentando las bases de dos proyectos en JAVA.

El primero es más pequeño y se basa en una aplicación de consola, y de eso vamos a hablar hoy.

Voy a ir creando una pequeña aplicación de consola que lee todas las líneas de un fichero de texto.

Es bastante simple, pero lo que quiero hacer es crear un proyecto con todas las necesidades que puede tener una aplicación de consola:
  • Librerías externas
  • Sistema de log
  • Fichero externo de configuración
  • Multidioma
  • Generación de un ejecutable (jar) para su posterior uso
Todo el código y los pasos están en el siguiente repositorio: https://github.com/tecnificados/lector

El entorno de trabajo con el que estoy trabajando es el siguiente:
  • Sistema operativo: Windows 10
  • Openjdk version "12.0.2" 2019-07-16
  • IDE: Eclipse 2019-06 (4.12.0)
El primer paso es crear con Maven un proyecto "quickstart" dentro de Eclipse (File -> New -> Maven Project) :



Con esto ya tendremos nuestra estructura lista. Y éste va ser el segundo commit del proyecto: c04808759483432e185fae554a215e682b981af8

Por defecto Maven nos deja el compilador de JAVA con la versión 5.



Ya que estamos utilizando el Openjdk 12, vamos a subirla a esta versión añadiendo estas líneas en el fichero pom.xml:


<maven.compiler.target>1.12</maven.compiler.target>
<maven.compiler.source>1.12</maven.compiler.source>

Podéis ver el detalle del cambio en este commit: 6c483c4abc3f46c0aea1b5679605ac3db27d251a

Si hacemos un "Maven Update", nos debe aparecer la versión correcta en el proyecto.

Ahora vamos a buscar una librería que nos ayude a leer ficheros. Mi favorita es "commons-io" del proyecto Apache. La incluimos en el fichero pom.xml para que sus objetos estén disponibles. Otro commit: 5fa357852024488ab5a43080ee51c446ea7a3c1c

Ahora vamos a hacer una pequeña prueba, vamos crear un pequeño archivo "fichero.txt" que va a tener 10 líneas. Y vamos a escribir unas líneas de código para contar las líneas del fichero utilizando el objeto FileUtils de "commons-io".

El código que escribimos es el siguiente:


List<String> readedLines = new ArrayList<String>();
try {
     readedLines = FileUtils.readLines(new File("fichero.txt"),"utf-8");
     System.out.println("Lineas: "+readedLines.size());
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

Tenemos que meter un try/catch por si el método "readLines" lanza una excepción.

Si ejecutamos este código, nos debería aparecer esta salida:

Lineas: 10


Hago un commit con todos estos cambios: 1287bbeaaf2c21021ce5432b4fd094ea0426554d

Hasta ahora no hemos hecho nada con el contenido del fichero, pero tenemos una lista en la variable readedLines donde está el contenido de cada línea.

Vamos a añadir más información al fichero de prueba, y vamos hacer que el programa nos escriba en pantalla cada una de ellas.

Sé que es muy simple, pero me sirve para demostrar que estamos leyendo el fichero.

Añadiendo estas líneas podremos ver el contenido de cada línea leída:


for (String actual:readedLines)
{
     System.out.println("\t"+actual);
}

Las podéis ver en el commit: d65b491461ba90ed8a1cdef121a1b043985fc733

El funcionamiento básico ya no va a evolucionar más.

Ahora vamos a mejorar el programa para que tenga unas características más profesionales.

Sistema de log

Voy a añadir la librería "logback", antes era más de log4j, pero como muchos sabéis ha quedado sin mantenimiento.

Añadimos la librería al fichero "pom.xml", y en la aplicación nos creamos una variable estática con esta línea:


private static final Logger log = LoggerFactory.getLogger(App.class);

Ya tenemos el log a nuestra disposición.

A partir de ahora todo lo que sale por pantalla, en lugar de usar "system.out" lo hago con el sistema de log que acabamos de añadir.

En la excepción en lugar de usar "log.info" utilizo "log.error".

Todos los cambios del sistema de log están disponibles en este commit: 94d2d8ee44347ede47e67cef3a92ccedd48e9583

Fichero de configuración externo

Ahora mismo se está leyendo el fichero "fichero.txt" y el nombre del fichero está a nivel de código, una práctica que no es muy recomendable.

Vamos a crear un fichero "conf.properties" donde se va a configurar este parámetro.

A continuación voy a crear un método "configuration()" que será el que realice la lógica de leer el fichero de configuración y asignar su valor.

En este commit están todos estos cambios: e33d60eea78b23eca3e07229e856a5fd5d09a6c7

Multidioma

En aplicaciones de consola, es raro que nos soliciten multidioma, pero todo es posible.

Aquí eclipse nos echa un cable, con su asistente en botón derecho -> source -> externalize strings.

Este asistente nos crea una clase "Message" para realizar la sustitución dinámica de las cadenas que seleccionemos.

Antes de lanzar el asistente he generado unas cuantas constantes, para evitar problemas.

He creado tres ficheros con traducciones:
  • messages.properties: es la configuración por defecto (inglés)
  • messages_en_EN.properties: inglés de Inglaterra
  • messages_es_ES.properties: español de España

Voy a dejar fijado este último con la siguiente línea:


Locale.setDefault(new Locale("es_ES"));


Si fijáramos otro como "fr_FR", al no existir, cargaría el contenido del messages.properties.

El un con todos los cambios que acabamos de generar es: a6033bf9c31cbacae035ae69432b85919714c88b

Antes de continuar voy a refactorizar un poco, no me gusta mucho la estructura que me ha generado el asistente.

Voy a generar una clase Constant con todas las constantes, y un paquete Util con las clases y los ficheros nuevos.



Todos los cambios los tenemos en este commit: 80aa109d65ddfadda75e20228e84ce585afb2ed6

Ejecutable Jar Completo

Y para terminar vamos a decirle a Maven que cuando genere un empaquetado lo haga con todas las librerías que utiliza, y especificarle cuál es la clase principal.

Todo esto lo conseguimos gracias al plugin Shade de Maven, sólo hay que retocar unas cuantas líneas en el pom.xml, y añadir un par de plugins. Podéis ver en detalle estos cambios aquí: 86369ce3d028b405eed691a556a5e7fcf90148ef

Después de esto si lanzamos un mvn package tendremos un jar con todas las librerías que necesita, y está listo para ser invocado con el comando: "java -jar lector.jar"

Espero que os sea de utilidad, ha sido una entrada muy larga, pero he conseguido hacer todo lo que quería en sólo 11 commits.

Entradas populares de este blog

Spring Boot: Página inicial con Bootstrap

  Este es el segundo artículo de la serie sobre Spring Boot que comenzamos hace dos semanas, si quieres ver el primero puedes acceder pulsando aquí . En el primer artículo vimos cómo descargar nuestro proyecto configurado para nuestros intereses y listo para ser importado en nuestro IDE (nosotros usaremos Eclipse ). Lo primero que vamos a hacer es importar el proyecto: File -> Import Existing Maven Projects Seleccionamos el fichero pom.xml en la carpeta donde lo hemos descomprimido y esperamos unos segundos Cuando acabe la importación, esta es la estructura que nos aparecerá: Con Spring Boot no necesitamos configurar el servidor, ya se encarga él de facilitarnos la vida. Lo único que tenemos que hacer es arrancar la clase BootApplication.java , que se encargará de arrancar Tomcat y dejar nuestra aplicación funcionando en el puerto 8080.  Y si todo fuera bien, podríamos acceder a través de la URL:  http://localhost:8080/ Pero ahora mismo tenemos un error de conexión c...

Redirección de puertos en Virtual Box

Continuando con mis anteriores "posts", vamos a terminar nuestro entorno de pruebas redirigiendo los puertos que nos interesan de la máquina virtual a nuestro PC. Con Virtual Box podemos configurar la red de diversas formas, una de ellas es redireccionar los puertos de la máquina virtual a la nuestra. Es bastante fácil y rápido de configurar, y lo que hace es que tengamos unos puertos destinados al entorno de desarrollo y otros para el entorno de pruebas. Ejemplo de uso:  - podemos usar el puerto 8080 para desarrollar en eclipse en nuestro entorno de desarrollo con Tomcat. - usaremos el puerto 80 para el Tomcat del entorno de pruebas Más adelante veremos cómo configurar las redes de virtual box para que sean máquinas independientes conectadas a nuestra red y más opciones. Vamos a hacer la redirección del puerto 22 para poder acceder a nuestra máquina virtual a través de uno de los clientes ssh más extendidos (y con nombre controvertido): ...

ASP.Net MVC: Subida de imágenes al servidor y recorte con Jcrop

Recientemente tuve que incluir, en un proyecto de ASP.Net MVC en el que estoy trabajando, un formulario donde un usuario podía subir su foto al perfil, y si el sistema detectaba que el tamaño de la imagen subida superaba el 100x100, había que recortarla. Esta premisa, aunque parece sencilla, encierra varios problemas técnicos a solucionar: 1) Subida de ficheros al servidor con ASP.Net MVC. 2) Recorte de foto y guardado. 3) Puntos a tener en cuenta: versiones de navegadores y otros aspectos técnicos. Vamos a ir viendo paso a paso cómo implementar esta práctica funcionalidad. Subida de ficheros al servidor con ASP.Net MVC Para subir ficheros al servidor desde la Vista, en Mvc se dispone de la clase System.Web.HttpPostedFileBase.  Para utilizarla, hay que seguir los pasos: - Declarar una propiedad de este tipo en el Model que se va a utilizar: public HttpPostedFileBase Fichero { get; set; } - Crear en la vista el formulario para realizar la subida ...