Cómo establecer archivo de propiedades en java

Muchas veces es necesario guardar ciertos parámetros en una aplicación que estamos desarrollando para un funcionamiento más óptimo de la misma. Gracias a esto, podemos crear aplicaciones que el usuario personalice: el idioma, el famoso look and feel, y todo lo que necesitemos vamos a poder guardarlo de una forma estandarizada cuya lectura va a ser muy simple gracias a la clase java.util.Properties que nos proporciona el JDK por defecto.

¿Qué es un archivo de propiedades?

Más comúnmente conocido con el anglicismo «archivo properties» o típicamente el archivo de configuración, es un simple archivo en el que podemos guardar diferentes propiedades o parámetros de configuración que la aplicación pueda leer y editar pudiendo así guardar el estado de la misma para futuros usos.

Un parámetro muy típico, por poner un ejemplo, es el parámetro del lenguaje. Muchas aplicaciones están traducidas a diferentes lenguajes y, al instalar dicho software, nos pregunta (entre otras muchas cosas) en qué idioma deseamos instalarlo. Ese dato se guardará en el archivo de configuración y la aplicación lo leerá siempre que se ejecute, para mostrar el texto en el lenguaje que se le ha ordenado. Si cambiamos más adelante el idioma, el valor de ese parámetro cambiará.

Si no tienes mucha experiencia en programación pensarás que es algo poco útil para sistemas pequeños típicos de programadores caseros, pero te equivocas: se usa muchísimo más de lo que parece. Evidentemente, este archivo de propiedades no va a tener la misma extensión en los típicos programas amateur que en los sistemas más complejos como, por ejemplo, Photoshop o cualquier sistema empresarial grande. Pero el caso es que, más grande o más pequeño, es común que las aplicaciones cuenten con un archivo para esta función.

Hoy os voy a enseñar cómo hacerlo (bien hecho) en Java. Y digo bien hecho porque se puede hacer de muchísimas formas, pero esta es la que me parece más óptima. Puedes crear tu archivo bajo los estándares que tu quieras y crear tus propios métodos de lectura y escritura de propiedades, pero aquí te voy a enseñar un estándar muy sencillo que te va a ahorra horas de trabajo y te va a proporcionar una interfaz de operaciones completísima.

Creando el archivo

Esto es lo más sencillo. Como ya he dicho, puedes establecer tu interfaz de operaciones y tu estándar de archivo. Pero si prefieres ahorrar tiempo y usar este método, debes atenerta a estas simples normas:

  • El archivo puede tener cualquier nombre, pero la extensión siempre debe ser .properties y, como es de esperar, puedes guardarlo en la ubicación que más te convenga.
  • El estándar de escritura de cada propiedad debe ser así: nombre_propidedad=valor_propiedad. Siendo sincero, no se si puedes poner espacios entre las palabras y el símbolo =. Cuando escribo nombre_propiedad no significa que tenga que tener obligatoriamente un guión bajo para separar palabras, sino que no puede contener espacios. Si eres más amigo de camel case, también puedes usar nombrePropiedad=valorPropiedad. Es exactamente igual de válido, la elección es tuya. La única norma es que no debe contener espacios y el token delimitador entre el nombre y el valor de la propiedad debe ser el símbolo =.

Para este tutorial voy a crear en una aplicación que ya tengo en funcionamiento un archivo llamado config.propoerties.

En la siguiente imagen podeis ver los parámetros que he incluido. He utilizado idioma inglés, pero no es necesario.

Leer parámetros desde nuestro archivo

Cada propiedad tendrá su propio valor. Mientras respetes las dos normas citadas en el punto anterior, tienes total libertad a la hora de asignar valores para tus atributos. Puedes crear valores con números, cadenas de texto y todo lo que se te ocurra.

Para conocer el estado de un parámetro debemos comenzar cargando el contenido del archivo con la clase java.io.InputStream. Cuando ya tengamos cargado nuestro archivo, en la clase java.io.Properties encontramos el métido getProperty(name_property). Con solo eso ya es suficiente. No obstante, vayamos con el código de nuestro ejemplo:

Properties config = new Properties();
    InputStream configInput = null;
    public void loadConfig(){
        try{
            configInput = new FileInputStream("config.properties");
            config.load(configInput);
            System.out.println(config.getProperty("first_start"));
            System.out.println(config.getProperty("look_and_feel"));
        } catch(Exception e){
            JOptionPane.showMessageDialog(null, "Error cargando configuración\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

Y el resultado que nos arroja es:

Escribir los parámetros

Cuando necesitemos cambiar o escribir el valor en alguno de los parámetros debemos recurrir en este caso al método setProperty(name_property, value_property) implementado en la misma clase java.util.Properties. Además, si antes usábamos el InputStream para cargar los datos, ahora usaremos la clase java.io.OutputStream para guardar los valores en el archivo. Un código base de ejemplo para entenderlo sería algo así:

public static Properties config = new Properties();
public static InputStream configInput = null;
public static OutputStream configOutput = null;

public void escribirPropiedades(){
        try{
            configOutput = new FileOutputStream("data/config.properties");
            config.setProperty("excel_vinculed", "null");
            config.setProperty("first_start", "1");
        } catch(Exception e){
            JOptionPane.showMessageDialog(null, "Error guardando configuración\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

Pero no me gusta como queda. Normalmente no tenemos un método que nos escribe cuando le da la gana un montón de propiedades, sino que necesitamos editar una propiedad puntualmente en cada trazo de código. Por tanto, lo normal es crear un método en nuestra entidad controladora (suponiendo que usamos el MVC) al que le pasemos por parámetro el nombre de la propiedad que deseamos editar y su valor, estandarizando así todo el método para nuestro programa. Por tanto, un código mucho mejor hecho sería el siguiente:

public static void setPropertyValue(String property, String value){
        try{
            configOutput = new FileOutputStream("data/config.properties");
            config.setProperty(property, value);
        } catch(Exception e){
            JOptionPane.showMessageDialog(null, "Error guardando configuración\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

 Conclusiones

Es mucho más sencillo de lo que podría parecer en un principio. Antes de conocer estos métodos, yo siempre andaba creando en cada programa mi propio archivo de configuración con una extensión que yo me inventaba. Tenía que crear, además, las operaciones necesarias para poder llamar a una propiedad o editarla mediante una única función. Y lleva mucho más rollo del que parece: para leer una propiedad tienes que cargar el archivo y recorrerlo línea por línea hasta encontrar la propiedad llamada y parar el bucle ahí. Si no se encuentra tienes que crear tu propia gestión de errores para que funcione todo perfectamente y hacer eso en cada programita que te haces retrasa mucho más de lo que parece a simple vista.

No obstante, creo que me ha servido para aprender mucho. El hecho de haber creado varias veces mi propio sistema de configuración me ha llevado a comprender ahora cómo funcionan los métodos a los que llamo aunque no los haya creado yo mismo. Es un valor añadido que no tendría si hubiera optado desde un principio por utilizar directamente las opreaciones ya implementadas.

Como he mencionado al principio, es raro que un programa no use este tipo de archivos. Ahora ya sabes cómo hacerlo. Dale vueltas al asunto y verás lo potente que es un sistema tan sencillo como este y todo lo que puede ayudarte. Te espero en los comentarios, hasta el próximo jueves.

4 comentarios

  1. Giancarlo

    Para que usas el configOutput ? no veo que lo vuelvas a usar.

    public void escribirPropiedades(){
    try{
    configOutput = new FileOutputStream(«data/config.properties»);
    config.setProperty(«excel_vinculed», «null»);
    config.setProperty(«first_start», «1»);
    } catch(Exception e){
    JOptionPane.showMessageDialog(null, «Error guardando configuración\n» + e.getMessage(), «Error», JOptionPane.ERROR_MESSAGE);
    }
    }

    • Urbano Villanueva

      Hola. Es posible que sea un error. Muchas veces, antes de programar cualquier algoritmo final o publicar el tutorial, suelo hacer pruebas de funcionamiento que implican la creación de variables para verificar el comportamiento. Es posible que tras una mejora ya no usara dicha variable y que sobre, hace mucho que no veo ese código, tendré que revisarlo. Gracias por tu atención!

  2. Esparaquia

    Buen aporte, solo tengo una pregunta al respecto:
    Porque cambian los valores una vez dentro del archivo, es decir al meomento de abrir el archivo, los valores tienen caracteres de mas como «\». Existe alguna forma de evitar eso?

    • Urbano Villanueva

      Lo cierto es que no se responderte a eso. Al fin y al cabo, será gestionado como la propia librería de properties lo implemente. Mientras te lea y te escriba bien y no provoque problemas yo no le daría mayor importancia. Otra cosa es que luego al pedirle los datos no lo haga bien, entonces es un error en la configuración o en el algoritmo que debe corregirse.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*