¿Cómo usar los archivos de propiedades Java?

219

Tengo una lista de pares clave / valor de valores de configuración que quiero almacenar como archivos de propiedades Java, y luego cargar e iterar.

Preguntas:

  • ¿Necesito almacenar el archivo en el mismo paquete que la clase que los cargará, o hay alguna ubicación específica donde deba colocarse?
  • ¿El archivo debe terminar en alguna extensión específica o está .txtbien?
  • ¿Cómo puedo cargar el archivo en el código?
  • ¿Y cómo puedo iterar a través de los valores dentro?
Haga clic en Upvote
fuente

Respuestas:

246

Puede pasar un InputStream a la Propiedad, por lo que su archivo puede estar prácticamente en cualquier lugar y llamar a cualquier cosa.

Properties properties = new Properties();
try {
  properties.load(new FileInputStream("path/filename"));
} catch (IOException e) {
  ...
}

Iterar como:

for(String key : properties.stringPropertyNames()) {
  String value = properties.getProperty(key);
  System.out.println(key + " => " + value);
}
Zed
fuente
¿Qué valor se devuelve cuando la clave no está presente en el archivo de propiedades?
Mitaksh Gupta
2
@MitakshGupta Si una propiedad con el nombre que pasó no se encuentra en el archivo o en la lista de propiedades por defecto, vuelve a aparecer null. Ver Javadoc
drigoangelo
3
¿Cómo se compara esto con lo properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); que es, getResourceAsStreamversus FileInputStream? ¿pros y contras?
Thufir
80
  • Usted puede almacenar el archivo en cualquier lugar que te gusta. Si desea mantenerlo en su archivo jar, querrá usarlo Class.getResourceAsStream()o ClassLoader.getResourceAsStream()acceder a él. Si está en el sistema de archivos, es un poco más fácil.

  • Cualquier extensión está bien, aunque .properties es más común en mi experiencia

  • Cargue el archivo usando Properties.load, pasando una InputStreamo una StreamReadersi está usando Java 6. (Si está usando Java 6, probablemente usaría UTF-8 y una codificación en Readerlugar de la codificación ISO-8859-1 predeterminada para una secuencia. )

  • Iterar a través de él como lo haría a través de un normal Hashtable(que se Propertiesderiva de), por ejemplo, usando keySet(). Alternativamente, puede usar la enumeración devuelta por propertyNames().

Jon Skeet
fuente
1
Gracias Jon, lo siguiente que sé es que buscaré algo sobre Joda y tú también responderás.
Llama
27

Si coloca el archivo de propiedades en el mismo paquete que la clase Foo, puede cargarlo fácilmente con

new Properties().load(Foo.class.getResourceAsStream("file.properties"))

Dado que Propiedades extiende Hashtable, puede iterar sobre los valores de la misma manera que lo haría en un Hashtable.

Si utiliza la extensión * .properties, puede obtener soporte para el editor, por ejemplo, Eclipse tiene un editor de archivos de propiedades.

Fabian Steeg
fuente
55
Usted puede hacer esto - pero no me gusta el almacenamiento de archivos de propiedades en el mismo paquete. Termina con archivos de propiedades repartidos por todo el lugar en su aplicación. Prefiero almacenar todos los archivos de propiedades en la raíz de la aplicación y cargarlos como "class.getResourceAsStream (" \ file.properties ")" o en alguna otra ubicación conocida.
Nate
Nate, eso es verdad. Sin embargo, en algunos escenarios se desconoce la ubicación implementada (por ejemplo, todo su componente en particular está incluido en algún archivo). En tales casos, puede ser bastante conveniente decir 'está con esa clase, donde sea que esa clase termine siendo'. Además, para evitar extender los archivos por todas partes, se puede usar un único paquete de configuración para todos los archivos de propiedades.
Fabian Steeg el
1
Fabian, ambos casos funcionan con mi comentario, se basa en el classpath, no en el sistema de archivos.
Nate
2
Para cualquiera que intente que funcione el ejemplo de Nate, la barra diagonal inversa debe reemplazarse por una barra diagonal. Entonces, en este caso: 'class.getResourceAsStream ("/ file.properties")'
hash_collision
12

Hay muchas formas de crear y leer propertiesarchivos:

  1. Almacene el archivo en el mismo paquete.
  2. Recomiende la .propertiesextensión, sin embargo, puede elegir la suya.
  3. Uso Tesis clases ubicadas en java.utilel paquete => Properties, ListResourceBundle, ResourceBundleclases.
  4. Para leer propiedades, use iterador o enumerador o métodos directos de Propertieso java.lang.Systemclase.

ResourceBundle clase:

 ResourceBundle rb = ResourceBundle.getBundle("prop"); // prop.properties
 System.out.println(rb.getString("key"));

Properties clase:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));
Adatapost
fuente
Hola AVD, ¿por qué solo necesitamos .propertiesextensión? ¿Qué tiene de malo la extensión '.txt'? por favor ayúdame
atish shimpi
@atishshimpi No se requiere mientras se trabaja con el tipo de Propiedades, pero es obligatorio para ResourceBundle - lea doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost
5

Esto carga el archivo de propiedades:

Properties prop = new Properties();
InputStream stream = ...; //the stream to the file
try {
  prop.load(stream);
} finally {
  stream.close();
}

Utilizo para colocar el archivo .properties en un directorio donde tengo todos los archivos de configuración, no lo combino con la clase que accede a él, pero aquí no hay restricciones.

Por el nombre ... Yo uso .properties por el bien de la verbosidad, no creo que debas llamarlo .properties si no quieres.

Alberto Zaccagni
fuente
Sin embargo, algunas "extensiones" de archivos de propiedades asumen la extensión .properties, por ejemplo, ResourceBundle utilizado en I18N.
Nate
5

Ejemplo:

Properties pro = new Properties();
FileInputStream in = new FileInputStream("D:/prop/prop.properties");
pro.load(in);
String temp1[];
String temp2[];
// getting values from property file
String username = pro.getProperty("usernamev3");//key value in prop file 
String password = pro.getProperty("passwordv3");//eg. username="zub"
String delimiter = ",";                         //password="abc"
temp1=username.split(delimiter);
temp2=password.split(delimiter);
zubair
fuente
¿Qué pasa si tienes 3 archivos de propiedad?
Angelina
4

Las propiedades se han convertido en legado. Preferencias clase se prefiere Propiedades.

Un nodo en una colección jerárquica de datos de preferencia. Esta clase permite que las aplicaciones almacenen y recuperen datos de configuración y preferencias del usuario y del sistema. Estos datos se almacenan de forma persistente en un almacén de respaldo dependiente de la implementación. Las implementaciones típicas incluyen archivos planos, registros específicos del sistema operativo, servidores de directorio y bases de datos SQL. El usuario de esta clase no necesita preocuparse por los detalles de la tienda de respaldo.

A diferencia de las propiedades que son pares clave-valor basados ​​en cadenas, la Preferencesclase tiene varios métodos utilizados para obtener y colocar datos primitivos en el almacén de datos de preferencias. Solo podemos usar los siguientes tipos de datos:

  1. Cuerda
  2. booleano
  3. doble
  4. flotador
  5. En t
  6. largo
  7. conjunto de bytes

Para cargar el archivo de propiedades, puede proporcionar una ruta absoluta o usarla getResourceAsStream()si el archivo de propiedades está presente en su ruta de clase.

package com.mypack.test;

import java.io.*;
import java.util.*;
import java.util.prefs.Preferences;

public class PreferencesExample {

    public static void main(String args[]) throws FileNotFoundException {
        Preferences ps = Preferences.userNodeForPackage(PreferencesExample.class);
        // Load file object
        File fileObj = new File("d:\\data.xml");
        try {
            FileInputStream fis = new FileInputStream(fileObj);
            ps.importPreferences(fis);
            System.out.println("Prefereces:"+ps);
            System.out.println("Get property1:"+ps.getInt("property1",10));

        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}

archivo xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preferences SYSTEM 'http://java.sun.com/dtd/preferences.dtd'>
<preferences EXTERNAL_XML_VERSION="1.0">
<root type="user">
<map />
<node name="com">
  <map />
  <node name="mypack">
    <map />
    <node name="test">
      <map>
        <entry key="property1" value="80" />
        <entry key="property2" value="Red" />
      </map>
    </node>
  </node>
</node>
</root>
</preferences>

Echa un vistazo a este artículo sobre la tienda de preferencias internas

Ravindra babu
fuente
3

En orden:

  1. Puede almacenar el archivo prácticamente en cualquier lugar.
  2. No es necesaria una extensión.
  3. Montecristo ha ilustrado cómo cargar esto. Eso debería funcionar bien.
  4. propertyNames () le ofrece una enumeración para recorrer en iteración.
Brian Agnew
fuente
2. no extension is necessary, ¿Pueden proporcionarme alguna referencia para esta declaración? Tengo confusión sobre eso.
atish shimpi
Tenga en cuenta que puede cargar las propiedades a través de una secuencia de entrada. Como tal, las propiedades no tienen conocimiento de dónde provino ese flujo de entrada (¿un archivo? ¿Un socket?) Y, en consecuencia, no pueden aplicar un estándar de nomenclatura
Brian Agnew
3

Por defecto, Java lo abre en el directorio de trabajo de su aplicación (este comportamiento realmente depende del sistema operativo utilizado). Para cargar un archivo, haga:

Properties props = new java.util.Properties();
FileInputStream fis new FileInputStream("myfile.txt");
props.load(fis)

Como tal, cualquier extensión de archivo se puede utilizar para el archivo de propiedades. Además, el archivo también se puede almacenar en cualquier lugar, siempre que pueda usar a FileInputStream.

En una nota relacionada, si utiliza un marco moderno, el marco puede proporcionar formas adicionales de abrir un archivo de propiedades. Por ejemplo, Spring proporciona una ClassPathResourcepara cargar un archivo de propiedades utilizando un nombre de paquete desde dentro de un archivo JAR.

En cuanto a iterar a través de las propiedades, una vez que se cargan las propiedades, se almacenan en el java.util.Propertiesobjeto, que ofrece el propertyNames()método.

Thierry-Dimitri Roy
fuente
3

Leer un archivo de propiedades y cargar su contenido en Properties

String filename = "sample.properties";
Properties properties = new Properties();

input = this.getClass().getClassLoader().getResourceAsStream(filename);
properties.load(input);

La siguiente es la forma eficiente de iterar sobre un Properties

    for (Entry<Object, Object> entry : properties.entrySet()) {

        System.out.println(entry.getKey() + " => " + entry.getValue());
    }
JoBⅈN
fuente
3

En Java 8 para obtener todas tus propiedades

public static Map<String, String> readPropertiesFile(String location) throws Exception {

    Map<String, String> properties = new HashMap<>();

    Properties props = new Properties();
    props.load(new FileInputStream(new File(location)));

    props.forEach((key, value) -> {
        properties.put(key.toString(), value.toString());
    });

    return properties;
}
Radouane ROUFID
fuente
2

1) Es bueno tener su archivo de propiedades en classpath, pero puede colocarlo en cualquier parte del proyecto.

A continuación se muestra cómo cargar el archivo de propiedades de classpath y leer todas las propiedades.

Properties prop = new Properties();
InputStream input = null;

try {

    String filename = "path to property file";
    input = getClass().getClassLoader().getResourceAsStream(filename);
    if (input == null) {
        System.out.println("Sorry, unable to find " + filename);
        return;
    }

    prop.load(input);

    Enumeration<?> e = prop.propertyNames();
    while (e.hasMoreElements()) {
        String key = (String) e.nextElement();
        String value = prop.getProperty(key);
        System.out.println("Key : " + key + ", Value : " + value);
    }

} catch (IOException ex) {
    ex.printStackTrace();
} finally {
    if (input != null) {
        try {
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2) Los archivos de propiedades tienen la extensión como .properties

Jitender Chahar
fuente
1

Aquí hay otra forma de iterar sobre las propiedades:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}
dertoni
fuente
2
Lo siento totalmente He revisado el código en la respuesta de la zeta y funciona bastante bien ... No sé lo que pensé en ese entonces ... En realidad, su solución es más bonito que el mío, creo que ...
dertoni
1

He escrito sobre este marco de propiedad para el año pasado. Proporcionará múltiples formas de cargar propiedades, y también las tendrá fuertemente tipadas.

Echa un vistazo a http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped le dará al desarrollador propiedades fuertemente tipadas. Fácil de integrar en proyectos existentes. Manejado por una gran serie de tipos de propiedades. Da la capacidad de inicializar propiedades de una línea a través de implementaciones de propiedades IO. Le da al desarrollador la capacidad de crear sus propios tipos de propiedad y propiedades io. La demostración web también está disponible, las capturas de pantalla se muestran arriba. También tenga una implementación estándar para un front-end web para administrar propiedades, si elige usarlo.

La documentación completa, tutorial, javadoc, preguntas frecuentes, etc. está disponible en la página web del proyecto.

FrederikH
fuente
0

Aquí listo clase estática

import java.io.*;
import java.util.Properties;
public class Settings {
    public static String Get(String name,String defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return props.getProperty(name);
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Integer Get(String name,Integer defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Integer.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static Boolean Get(String name,Boolean defVal){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);
            reader.close();
            return Boolean.valueOf(props.getProperty(name));
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
            return defVal;
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
            return defVal;
        } catch (Exception ex){
            logger.error(ex);
            return defVal;
        }
    }
    public static void Set(String name, String value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer, Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Integer value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
    public static void Set(String name, Boolean value){
        File configFile = new File(Variables.SETTINGS_FILE);
        try {
            Properties props = new Properties();
            FileReader reader = new FileReader(configFile);
            props.load(reader);
            props.setProperty(name, value.toString());
            FileWriter writer = new FileWriter(configFile);
            props.store(writer,Variables.SETTINGS_COMMENT);
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
            logger.error(ex);
        } catch (IOException ex) {
            // I/O error
            logger.error(ex);
        } catch (Exception ex){
            logger.error(ex);
        }
    }
}

Aquí muestra:

Settings.Set("valueName1","value");
String val1=Settings.Get("valueName1","value");
Settings.Set("valueName2",true);
Boolean val2=Settings.Get("valueName2",true);
Settings.Set("valueName3",100);
Integer val3=Settings.Get("valueName3",100);
vitalinvent
fuente
0

Puede cargar el archivo de propiedades demandando de la siguiente manera:

InputStream is = new Test().getClass().getClassLoader().getResourceAsStream("app.properties");
        Properties props =  new Properties();
        props.load(is);

Y luego puedes iterar sobre el mapa usando una expresión lambda como:

props.stringPropertyNames().forEach(key -> {
            System.out.println("Key is :"+key + " and Value is :"+props.getProperty(key));
        });
Piyush Dash
fuente
0

en mi opinión, otras formas están en desuso cuando podemos hacerlo de la manera más simple:

@PropertySource("classpath:application.properties")
public class SomeClass{

    @Autowired
    private Environment env;

    public void readProperty() {
        env.getProperty("language");
    }

}

¡Es tan simple pero creo que es la mejor manera! Disfrutar

Sobhan
fuente