Come utilizzare i file delle proprietà Java?


219

Ho un elenco di coppie chiave / valore di valori di configurazione che voglio archiviare come file delle proprietà Java e successivamente caricare e scorrere.

Domande:

  • Devo archiviare il file nello stesso pacchetto della classe che li caricherà o c'è un percorso specifico in cui dovrebbe essere collocato?
  • Il file deve terminare con un'estensione specifica o è .txtOK?
  • Come posso caricare il file nel codice
  • E come posso scorrere i valori all'interno?

Risposte:


246

È possibile passare un InputStream alla proprietà, quindi il file può essere praticamente ovunque e chiamato qualsiasi cosa.

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

Iterare come:

for(String key : properties.stringPropertyNames()) {
  String value = properties.getProperty(key);
  System.out.println(key + " => " + value);
}

Quale valore viene restituito quando la chiave non è presente nel file delle proprietà?
Mitaksh Gupta,

2
@MitakshGupta Se una proprietà con il nome che hai passato non è stata trovata nel file o nell'elenco delle proprietà predefinite, si ripresenta null. Vedi Javadoc
drigoangelo,

3
come si confronta con properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); quello è, getResourceAsStreamcontro FileInputStream? pro e contro?
Giovedì

80
  • È possibile memorizzare il file di qualsiasi luogo che ti piace. Se vuoi tenerlo nel tuo file jar, ti consigliamo di utilizzarlo Class.getResourceAsStream()o ClassLoader.getResourceAsStream()di accedervi. Se è nel file system è leggermente più semplice.

  • Qualsiasi estensione va bene, sebbene .properties sia più comune nella mia esperienza

  • Caricare il file utilizzando Properties.load, passando in una InputStreamo StreamReaderse si sta utilizzando Java 6. (Se si sta utilizzando Java 6, probabilmente sarei usare UTF-8 e un Readerposto del default ISO-8859-1 codifica per un flusso. )

  • Scorrere attraverso di essa mentre si scorreva un normale Hashtable(da cui Propertiesderiva), ad esempio usando keySet(). In alternativa, è possibile utilizzare l'enumerazione restituita da propertyNames().


1
Grazie Jon, la prossima cosa che so sarà che cercherò qualcosa su Joda e risponderai anche a quello.
Fiamma

27

Se si inserisce il file delle proprietà nello stesso pacchetto della classe Foo, è possibile caricarlo facilmente con

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

Dato che Proprietà estende Hashtable è possibile scorrere i valori nello stesso modo in cui si farebbe in Hashtable.

Se si utilizza l'estensione * .properties è possibile ottenere il supporto dell'editor, ad esempio Eclipse ha un editor di file delle proprietà.


5
È possibile fare questo - ma io non gradire la memorizzazione di file di proprietà nello stesso pacchetto. Si finisce con i file delle proprietà sparsi ovunque nell'area dell'applicazione. Preferirei piuttosto archiviare tutti i file delle proprietà nella radice dell'app e caricarli come "class.getResourceAsStream (" \ file.properties ")" o in qualche altra posizione nota.
Nate,

Nate, è vero. Tuttavia, in alcuni scenari la posizione distribuita non è nota (ad es. Tutto il componente specifico è raggruppato in un archivio). In questi casi può essere abbastanza conveniente dire "è con quella classe, ovunque quella classe finisca per essere". Inoltre, per evitare di diffondere i file ovunque, è possibile utilizzare un singolo pacchetto di configurazione per tutti i file delle proprietà.
Fabian Steeg,

1
Fabian, entrambi i casi funzionano con il mio commento - si basa sul percorso di classe - non sul filesystem.
Nate,

2
Per chiunque cerchi di far funzionare l'esempio di Nate, la barra rovesciata deve essere sostituita con una barra. Quindi in questo caso: 'class.getResourceAsStream ("/ file.properties")'
hash_collision

12

Esistono molti modi per creare e leggere propertiesfile:

  1. Archivia il file nello stesso pacchetto.
  2. Consiglia l' .propertiesestensione ma puoi scegliere la tua.
  3. Usa Tesi classi situate al java.utilpacchetto => Properties, ListResourceBundle, ResourceBundleclassi.
  4. Per leggere le proprietà, utilizzare iteratore o enumeratore o metodi diretti Propertieso di 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"));

Ciao AVD, perché abbiamo bisogno .propertiessolo dell'estensione? cosa c'è di sbagliato con l'estensione '.txt'? per favore aiutatemi.
Atish Shimpi,

@atishshimpi Non richiesto quando si lavora con il tipo Proprietà ma è obbligatorio per ResourceBundle - leggi doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost

5

Questo carica il file delle proprietà:

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

Uso per mettere il file .properties in una directory in cui ho tutti i file di configurazione, non lo metto insieme alla classe che vi accede, ma qui non ci sono restrizioni.

Per il nome ... Uso .properties per amor di verbosità, non credo che dovresti chiamarlo .properties se non vuoi.


Tuttavia, alcune "estensioni" dei file delle proprietà assumono l'estensione .properties, ad esempio ResourceBundle utilizzato in I18N.
Nate,

5

Esempio:

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

cosa succede se hai 3 file di proprietà?
Angelina,

4

Le proprietà sono diventate eredità. La classe delle preferenze è preferita a Proprietà.

Un nodo in una raccolta gerarchica di dati sulle preferenze. Questa classe consente alle applicazioni di archiviare e recuperare le preferenze dell'utente e del sistema e i dati di configurazione. Questi dati vengono archiviati in modo persistente in un archivio di supporto dipendente dall'implementazione. Le implementazioni tipiche includono file flat, registri specifici del sistema operativo, server di directory e database SQL. L'utente di questa classe non deve preoccuparsi dei dettagli del negozio di supporto.

A differenza delle proprietà che sono coppie chiave-valore basate su String, la Preferencesclasse ha diversi metodi usati per ottenere e inserire dati primitivi nell'archivio dati Preferenze. Possiamo usare solo i seguenti tipi di dati:

  1. Corda
  2. booleano
  3. Doppio
  4. galleggiante
  5. int
  6. lungo
  7. array di byte

Per caricare il file delle proprietà, è possibile fornire un percorso assoluto oppure utilizzare getResourceAsStream()se il file delle proprietà è presente nel percorso di 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();
        }
    }
}

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

Dai un'occhiata a questo articolo sugli store interni delle preferenze


3

In ordine:

  1. Puoi archiviare il file praticamente ovunque.
  2. non è necessaria alcuna estensione.
  3. Montecristo ha illustrato come caricare questo. Dovrebbe funzionare benissimo.
  4. propertyNames () fornisce un'enumerazione attraverso cui scorrere.

2. no extension is necessary, Per favore, mi può fornire qualsiasi riferimento per questa affermazione, per favore. Ho confusione su questo.
Atish Shimpi,

Si noti che è possibile caricare le proprietà tramite un flusso di input. Pertanto, le proprietà non sono a conoscenza della provenienza di quell'inputstream (un file? Un socket?) E di conseguenza non possono applicare uno standard di denominazione
Brian Agnew,

3

Per impostazione predefinita, Java lo apre nella directory di lavoro dell'applicazione (questo comportamento in realtà dipende dal sistema operativo utilizzato). Per caricare un file, eseguire:

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

Pertanto, qualsiasi estensione di file può essere utilizzata per il file delle proprietà. Inoltre, il file può essere archiviato ovunque, purché sia ​​possibile utilizzare a FileInputStream.

In una nota correlata se si utilizza un framework moderno, il framework può fornire modi aggiuntivi per aprire un file delle proprietà. Ad esempio, Spring fornisce a ClassPathResourceper caricare un file delle proprietà utilizzando un nome di pacchetto all'interno di un file JAR.

Per quanto riguarda l'iterazione attraverso le proprietà, una volta caricate le proprietà vengono memorizzate java.util.Propertiesnell'oggetto, che offre il propertyNames()metodo.


3

Leggere un file delle proprietà e caricarne il contenuto in Properties

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

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

Di seguito è riportato il modo efficace per scorrere su a Properties

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

        System.out.println(entry.getKey() + " => " + entry.getValue());
    }

3

In Java 8 per ottenere tutte le tue proprietà

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

2

1) È bene avere il tuo file di proprietà in classpath ma puoi posizionarlo ovunque nel progetto.

Di seguito è riportato come caricare il file delle proprietà dal percorso di classe e leggere tutte le proprietà.

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) I file delle proprietà hanno l'estensione come .properties


1

Ecco un altro modo per scorrere le proprietà:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}

2
Mi dispiace totalmente Ho esaminato il codice nella risposta di Zed e funziona abbastanza bene ... Non so cosa pensassi allora ... In realtà la sua soluzione è più bella della mia, penso ...
Dertoni

1

Ho scritto su questo framework di proprietà per l'ultimo anno. Fornirà diversi modi per caricare le proprietà e le avrà anche fortemente tipizzate.

Dai un'occhiata a http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped fornirà allo sviluppatore proprietà fortemente tipizzate. Facile da integrare in progetti esistenti. Gestito da una grande serie per tipi di proprietà. Offre la possibilità di inizializzare su una riga le proprietà tramite implementazioni di IO di proprietà. Offre allo sviluppatore la possibilità di creare i propri tipi di proprietà e proprietà di proprietà. È disponibile anche la demo Web, schermate mostrate sopra. Inoltre, se si sceglie di utilizzarlo, è anche disponibile un'implementazione standard per un front-end Web per la gestione delle proprietà.

Documentazione completa, tutorial, javadoc, faq ecc. Sono disponibili sulla pagina web del progetto.


0

Qui pronto classe statica

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

Ecco un esempio:

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

0

È possibile caricare il file delle proprietà facendo causa al seguente modo:

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

E quindi puoi iterare sulla mappa usando un'espressione lambda come:

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

0

secondo me altri modi sono deprecati quando possiamo farlo in modo molto semplice come di seguito:

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

    @Autowired
    private Environment env;

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

}

è così semplice ma penso che sia il modo migliore !! Godere

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.