Como usar arquivos de propriedades Java?

219

Eu tenho uma lista de pares chave / valor de valores de configuração que desejo armazenar como arquivos de propriedades Java e, posteriormente, carregar e iterar.

Questões:

  • Preciso armazenar o arquivo no mesmo pacote da classe que os carregará ou existe algum local específico em que ele deve ser colocado?
  • O arquivo precisa terminar em alguma extensão específica ou está .txtOK?
  • Como posso carregar o arquivo no código
  • E como posso percorrer os valores internos?
Click Voto a favor
fonte

Respostas:

246

Você pode passar um InputStream para a propriedade, para que seu arquivo possa estar em qualquer lugar e chamado de qualquer coisa.

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
fonte
Qual valor é retornado quando a chave não está presente no arquivo de propriedades?
Mitaksh Gupta
2
@MitakshGupta Se uma propriedade com o nome que você passou não for encontrada no arquivo ou na lista de propriedades padrão, ela será repetida null. Veja Javadoc
drigoangelo
3
como isso se compara com o properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); que é getResourceAsStreamversus FileInputStream? prós e contras?
Thufir
80
  • Você pode armazenar o arquivo em qualquer lugar que desejar. Se você deseja mantê-lo em seu arquivo jar, use Class.getResourceAsStream()ou ClassLoader.getResourceAsStream()acesse-o. Se estiver no sistema de arquivos, é um pouco mais fácil.

  • Qualquer extensão é boa, embora .properties seja mais comum em minha experiência

  • Carregue o arquivo usando Properties.load, passando um InputStreamou a StreamReaderse você estiver usando o Java 6. (Se você estiver usando o Java 6, eu provavelmente usaria UTF-8 e a em Readervez da codificação ISO-8859-1 padrão para um fluxo. )

  • Iterar através dele como você itera através de um normal Hashtable(que Propertiesderiva de), por exemplo, usando keySet(). Como alternativa, você pode usar a enumeração retornada por propertyNames().

Jon Skeet
fonte
1
Obrigado Jon, a próxima coisa que sei é que procurarei algo no joda e você também responderá.
Chama
27

Se você colocar o arquivo de propriedades no mesmo pacote da classe Foo, poderá carregá-lo facilmente com

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

Dado que o Properties estende o Hashtable, você pode iterar os valores da mesma maneira que faria em um Hashtable.

Se você usar a extensão * .properties, poderá obter suporte do editor, por exemplo, o Eclipse possui um editor de arquivo de propriedades.

Fabian Steeg
fonte
5
Você pode fazer isso - mas eu não gosto de armazenar arquivos de propriedades no mesmo pacote. Você acaba com arquivos de propriedades espalhados por todo o lugar no seu aplicativo. Prefiro armazenar todos os arquivos de propriedades na raiz do aplicativo e carregá-los como "class.getResourceAsStream (" \ file.properties ")" ou em outro local conhecido.
Nate
Nate, isso é verdade. No entanto, em alguns cenários, o local implantado não é conhecido (por exemplo, tudo do seu componente específico é agrupado em algum arquivo morto). Nesses casos, pode ser bastante conveniente dizer 'é com essa classe, onde quer que essa classe acabe'. Também para evitar espalhar os arquivos por todo o lado, um único pacote de configuração pode ser usado para todos os arquivos de propriedades.
Fabian Steeg
1
Fabian, os dois casos funcionam com o meu comentário - é baseado no caminho da classe - e não no sistema de arquivos.
Nate
2
Para quem tenta obter o exemplo de Nate, a barra invertida deve ser substituída por uma barra invertida. Portanto, neste caso: 'class.getResourceAsStream ("/ file.properties")'
hash_collision
12

Existem várias maneiras de criar e ler propertiesarquivos:

  1. Armazene o arquivo no mesmo pacote.
  2. Recomende a .propertiesextensão, no entanto, você pode escolher o seu.
  3. Use teses aulas localizados em java.utilpacote => Properties, ListResourceBundle, ResourceBundleclasses.
  4. Para ler propriedades, use o iterador ou enumerador ou métodos diretos Propertiesou java.lang.Systemclasse.

ResourceBundle classe:

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

Properties classe:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));
adatapost
fonte
Oi AVD, por que precisamos .propertiesapenas de extensão? o que há de errado com a extensão '.txt'? por favor me ajude.
Atish shimpi
@atishshimpi Não é necessário ao trabalhar com o tipo Properties, mas é obrigatório para ResourceBundle - leia doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost
5

Isso carrega o arquivo de propriedades:

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

Eu uso para colocar o arquivo .properties em um diretório em que tenho todos os arquivos de configuração, não o reuno com a classe que o acessa, mas não há restrições aqui.

Para o nome ... eu uso .properties para fins de verbosidade, acho que você não deve nomear .properties se não quiser.

Alberto Zaccagni
fonte
No entanto, algumas "extensões" dos arquivos de propriedades assumem a extensão .properties - por exemplo, ResourceBundle usado no I18N.
Nate
5

Exemplo:

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
fonte
e se você tiver 3 arquivos de propriedades?
Angelina
4

Propriedades tornou-se legado. A classe Preferences é preferida a Properties.

Um nó em uma coleção hierárquica de dados de preferência. Essa classe permite que os aplicativos armazenem e recuperem dados de preferência e configuração do usuário e do sistema. Esses dados são armazenados persistentemente em um armazenamento de backup dependente da implementação. As implementações típicas incluem arquivos simples, registros específicos do SO, servidores de diretório e bancos de dados SQL. O usuário desta classe não precisa se preocupar com os detalhes do armazenamento de suporte.

Diferentemente das propriedades que são pares de valores-chave baseados em String, a Preferencesclasse possui vários métodos usados ​​para obter e colocar dados primitivos no repositório de dados Preferências. Podemos usar apenas os seguintes tipos de dados:

  1. Corda
  2. boleano
  3. Duplo
  4. flutuador
  5. int
  6. longo
  7. matriz de bytes

Para carregar o arquivo de propriedades, você pode fornecer o caminho absoluto ou usar getResourceAsStream()se o arquivo de propriedades estiver presente em seu caminho de classe.

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();
        }
    }
}

arquivo 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>

Dê uma olhada neste artigo sobre informações internas da loja de preferências

Ravindra babu
fonte
3

Em ordem:

  1. Você pode armazenar o arquivo praticamente em qualquer lugar.
  2. nenhuma extensão é necessária.
  3. Montecristo ilustrou como carregar isso. Isso deve funcionar bem.
  4. propertyNames () fornece uma enumeração para iterar.
Brian Agnew
fonte
2. no extension is necessaryVocê pode me fornecer qualquer referência para esta declaração, por favor. Eu tenho confusão nisso.
Atish shimpi
Observe que você pode carregar as propriedades por meio de um fluxo de entrada. Como tal, as propriedades não têm conhecimento de onde que inputstream veio (um arquivo de uma tomada?) E, consequentemente, não pode impor um padrão de nomenclatura
Brian Agnew
3

Por padrão, o Java o abre no diretório de trabalho do seu aplicativo (esse comportamento realmente depende do sistema operacional usado). Para carregar um arquivo, faça:

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

Como tal, qualquer extensão de arquivo pode ser usada para o arquivo de propriedades. Além disso, o arquivo também pode ser armazenado em qualquer lugar, desde que você possa usar um FileInputStream.

Em uma nota relacionada, se você usar uma estrutura moderna, a estrutura poderá fornecer maneiras adicionais de abrir um arquivo de propriedades. Por exemplo, o Spring fornece um ClassPathResourcepara carregar um arquivo de propriedades usando um nome de pacote de dentro de um arquivo JAR.

Quanto à iteração pelas propriedades, uma vez carregadas, elas são armazenadas no java.util.Propertiesobjeto, que oferece o propertyNames()método.

Thierry-Dimitri Roy
fonte
3

Lendo um arquivo de propriedades e carregando seu conteúdo para Properties

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

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

A seguir, é apresentada a maneira eficiente de iterar em um Properties

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

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

No Java 8, para obter todas as suas propriedades

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
fonte
2

1) É bom ter seu arquivo de propriedades no caminho de classe, mas você pode colocá-lo em qualquer lugar do projeto.

Abaixo está como você carrega o arquivo de propriedades do classpath e lê todas as propriedades.

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) Os arquivos de propriedades têm a extensão como .properties

Jitender Chahar
fonte
1

Aqui está outra maneira de iterar sobre as propriedades:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}
dertoni
fonte
2
Eu sinto muito. Eu revi o código na resposta de Zed e ele funciona muito bem ... Eu não sei o que eu pensava naquela época ... Na verdade a sua solução é mais agradável do que a minha, eu acho ...
dertoni
1

Eu escrevi sobre essa estrutura de propriedades durante o último ano. Ele fornecerá várias maneiras de carregar propriedades e também será fortemente digitado.

Dê uma olhada em http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped fornecerá ao desenvolvedor propriedades fortemente digitadas. Fácil de integrar em projetos existentes. Manipulado por uma grande série de tipos de propriedade. Permite a inicialização de uma linha de propriedades por meio de implementações de E / S de propriedades. Dá ao desenvolvedor a capacidade de criar tipos de propriedade e io's de propriedade. Também está disponível uma demonstração na Web, capturas de tela mostradas acima. Também tenha uma implementação padrão para um front end da Web para gerenciar propriedades, se você optar por usá-lo.

Documentação completa, tutorial, javadoc, faq etc. está disponível na página do projeto.

FrederikH
fonte
0

Aqui estática classe pronta

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);
        }
    }
}

Aqui exemplo:

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
fonte
0

Você pode carregar o arquivo de propriedades processando da seguinte maneira:

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

E então você pode iterar sobre o mapa usando uma expressão lambda como:

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

na minha opinião, outras maneiras são preteridas quando podemos fazer isso de maneira muito simples, como abaixo:

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

    @Autowired
    private Environment env;

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

}

é tão simples, mas acho que é o melhor caminho !! Aproveitar

Sobhan
fonte