Wie verwende ich Java-Eigenschaftendateien?

219

Ich habe eine Liste von Schlüssel / Wert-Paaren von Konfigurationswerten, die ich als Java-Eigenschaftendateien speichern und später laden und durchlaufen möchte.

Fragen:

  • Muss ich die Datei im selben Paket speichern wie die Klasse, die sie laden wird, oder gibt es einen bestimmten Speicherort, an dem sie abgelegt werden soll?
  • Muss die Datei mit einer bestimmten Erweiterung enden oder ist sie in .txtOrdnung?
  • Wie kann ich die Datei in den Code laden?
  • Und wie kann ich die darin enthaltenen Werte durchlaufen?
Klicken Sie auf Upvote
quelle

Antworten:

245

Sie können einen InputStream an die Eigenschaft übergeben, sodass sich Ihre Datei praktisch überall befinden und alles aufrufen kann.

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

Iterieren als:

for(String key : properties.stringPropertyNames()) {
  String value = properties.getProperty(key);
  System.out.println(key + " => " + value);
}
Zed
quelle
Welcher Wert wird zurückgegeben, wenn der Schlüssel nicht in der Eigenschaftendatei vorhanden ist?
Mitaksh Gupta
2
@MitakshGupta Wenn eine Eigenschaft mit dem von Ihnen übergebenen Namen nicht in der Datei oder in der Liste der Standardeigenschaften gefunden wird, wird sie wiederholt null. Siehe Javadoc
Drigoangelo
3
Wie funktioniert das Vergleichen mit properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); dem heißt, im getResourceAsStreamVergleich zu FileInputStream? Vor-und Nachteile?
Thufir
80
  • Sie können die Datei an einem beliebigen Ort speichern. Wenn Sie es in Ihrer JAR-Datei behalten möchten, möchten Sie es verwenden Class.getResourceAsStream()oder ClassLoader.getResourceAsStream()darauf zugreifen. Wenn es sich im Dateisystem befindet, ist es etwas einfacher.

  • Jede Erweiterung ist in Ordnung, obwohl .properties meiner Erfahrung nach häufiger vorkommt

  • Laden Sie die Datei mit Properties.load, vorbei in einem InputStreamoder StreamReaderwenn Sie mit Java 6 (Wenn Sie werden mit Hilfe von Java 6, würde ich wahrscheinlich verwenden UTF-8 und eine Readeranstelle der Standard - ISO-8859-1 - Codierung für einen Stream. )

  • Durchlaufen Sie es, wie Sie es durch eine Normalität Hashtable(die sich daraus Propertiesergibt) durchlaufen würden , z keySet(). Alternativ können Sie die von zurückgegebene Aufzählung verwenden propertyNames().

Jon Skeet
quelle
1
Danke Jon, als nächstes weiß ich, dass ich etwas über Joda nachschlagen werde und du wirst das auch beantworten.
Flamme
27

Wenn Sie die Eigenschaftendatei in dasselbe Paket wie die Klasse Foo einfügen, können Sie sie problemlos mit laden

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

Da Eigenschaften Hashtable erweitern, können Sie die Werte auf dieselbe Weise wie in einer Hashtable durchlaufen.

Wenn Sie die Erweiterung * .properties verwenden, erhalten Sie Editorunterstützung, z. B. verfügt Eclipse über einen Editor für Eigenschaftendateien.

Fabian Steeg
quelle
5
Sie können dies tun - aber ich mag es nicht, Eigenschaftendateien im selben Paket zu speichern. Am Ende haben Sie Eigenschaftendateien, die über den gesamten Ort in Ihrer Anwendung verteilt sind. Ich würde viel lieber alle Eigenschaftendateien im Stammverzeichnis der App speichern und sie als "class.getResourceAsStream (" \ file.properties ")" oder an einem anderen bekannten Speicherort laden.
Nate
Nate, das stimmt. In einigen Szenarien ist der bereitgestellte Speicherort jedoch nicht bekannt (z. B. ist die gesamte Komponente in einem Archiv gebündelt). In solchen Fällen kann es sehr praktisch sein zu sagen, "es ist mit dieser Klasse, wo immer diese Klasse endet". Um zu vermeiden, dass die Dateien überall verteilt werden, kann ein einziges Konfigurationspaket für alle Eigenschaftendateien verwendet werden.
Fabian Steeg
1
Fabian, beide Fälle funktionieren mit meinem Kommentar - er basiert auf dem Klassenpfad - nicht auf dem Dateisystem.
Nate
2
Für alle, die versuchen, Nates Beispiel zum Laufen zu bringen, sollte der Backslash durch einen Forward Slash ersetzt werden. Also in diesem Fall: 'class.getResourceAsStream ("/ file.properties")'
hash_collision
12

Es gibt viele Möglichkeiten, propertiesDateien zu erstellen und zu lesen :

  1. Speichern Sie die Datei im selben Paket.
  2. .propertiesErweiterung empfehlen, aber Sie können Ihre eigene wählen.
  3. Verwenden Thesen Klassen an sich java.utilPaket => Properties, ListResourceBundle, ResourceBundleKlassen.
  4. Verwenden Sie zum Lesen von Eigenschaften den Iterator oder Enumerator oder direkte Methoden von Propertiesoder java.lang.Systemclass.

ResourceBundle Klasse:

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

Properties Klasse:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));
Adatapost
quelle
Hallo AVD, warum brauchen wir nur eine .propertiesErweiterung? Was ist falsch an der Erweiterung '.txt'? Bitte helfen Sie mir.
Atish Shimpi
@atishshimpi Wird bei der Arbeit mit dem Eigenschaftstyp nicht benötigt, ist jedoch für ResourceBundle obligatorisch - lesen Sie doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost
5

Dadurch wird die Eigenschaftendatei geladen:

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

Ich verwende die .properties-Datei in einem Verzeichnis, in dem ich alle Konfigurationsdateien habe. Ich füge sie nicht mit der Klasse zusammen, die darauf zugreift, aber hier gibt es keine Einschränkungen.

Für den Namen ... Ich benutze .properties aus Gründen der Ausführlichkeit. Ich denke nicht, dass Sie es .properties nennen sollten, wenn Sie nicht wollen.

Alberto Zaccagni
quelle
Einige "Erweiterungen" von Eigenschaftendateien setzen jedoch die Erweiterung .properties voraus - beispielsweise das in I18N verwendete ResourceBundle.
Nate
5

Beispiel:

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
quelle
Was ist, wenn Sie 3 Eigentumsdateien haben?
Angelina
4

Eigenschaften sind Vermächtnis geworden. Die Voreinstellungsklasse wird den Eigenschaften vorgezogen.

Ein Knoten in einer hierarchischen Sammlung von Präferenzdaten. Mit dieser Klasse können Anwendungen Benutzer- und Systemeinstellungen sowie Konfigurationsdaten speichern und abrufen. Diese Daten werden dauerhaft in einem implementierungsabhängigen Sicherungsspeicher gespeichert. Typische Implementierungen umfassen Flatfiles, betriebssystemspezifische Register, Verzeichnisserver und SQL-Datenbanken. Der Benutzer dieser Klasse muss sich nicht mit Details des Hintergrundspeichers befassen.

Im Gegensatz zu Eigenschaften, bei denen es sich um Zeichenfolgen-basierte Schlüssel-Wert-Paare handelt, verfügt die PreferencesKlasse über verschiedene Methoden zum Abrufen und Einfügen primitiver Daten in den Einstellungsdatenspeicher. Wir können nur die folgenden Datentypen verwenden:

  1. String
  2. Boolescher Wert
  3. doppelt
  4. schweben
  5. int
  6. lange
  7. Byte-Array

Zum Laden der Eigenschaftendatei können Sie entweder einen absoluten Pfad angeben oder verwenden, getResourceAsStream()wenn die Eigenschaftendatei in Ihrem Klassenpfad vorhanden ist.

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

XML-Datei:

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

Schauen Sie sich diesen Artikel über Interna des Preferials Store an

Ravindra Babu
quelle
3

In Ordnung:

  1. Sie können die Datei so ziemlich überall speichern.
  2. Es ist keine Verlängerung erforderlich.
  3. Montecristo hat gezeigt , wie dies geladen wird. Das sollte gut funktionieren.
  4. propertyNames () gibt Ihnen eine Aufzählung zum Durchlaufen.
Brian Agnew
quelle
2. no extension is necessaryKönnen Sie mir bitte eine Referenz für diese Aussage geben? Ich habe Verwirrung darüber.
Atish Shimpi
Beachten Sie, dass Sie die Eigenschaften über einen Eingabestream laden können. Daher wissen die Eigenschaften nicht, woher dieser Eingabestream stammt (eine Datei? Ein Socket?) Und können daher keinen Namensstandard erzwingen
Brian Agnew,
3

Standardmäßig öffnet Java es im Arbeitsverzeichnis Ihrer Anwendung (dieses Verhalten hängt tatsächlich vom verwendeten Betriebssystem ab). Gehen Sie wie folgt vor, um eine Datei zu laden:

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

Daher kann jede Dateierweiterung für die Eigenschaftendatei verwendet werden. Darüber hinaus kann die Datei auch überall gespeichert werden, solange Sie a verwenden können FileInputStream.

Wenn Sie ein modernes Framework verwenden, bietet das Framework möglicherweise zusätzliche Möglichkeiten zum Öffnen einer Eigenschaftendatei. Beispielsweise bietet Spring eine ClassPathResourceOption zum Laden einer Eigenschaftendatei unter Verwendung eines Paketnamens aus einer JAR-Datei.

Beim Durchlaufen der Eigenschaften werden die Eigenschaften nach dem Laden im java.util.PropertiesObjekt gespeichert , das die propertyNames()Methode anbietet .

Thierry-Dimitri Roy
quelle
3

Lesen einer Eigenschaftendatei und Laden ihres Inhalts in Properties

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

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

Das Folgende ist der effiziente Weg, um über a zu iterieren Properties

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

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

In Java 8 erhalten Sie alle Ihre Eigenschaften

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

1) Es ist gut, Ihre Eigenschaftendatei im Klassenpfad zu haben, aber Sie können sie an einer beliebigen Stelle im Projekt platzieren.

Im Folgenden wird beschrieben, wie Sie die Eigenschaftendatei aus dem Klassenpfad laden und alle Eigenschaften lesen.

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) Eigenschaftendateien haben die Erweiterung .properties

Jitender Chahar
quelle
1

Hier ist eine andere Möglichkeit, die Eigenschaften zu durchlaufen:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}
dertoni
quelle
2
Es tut mir total leid. Ich habe den Code in Zeds Antwort überprüft und er funktioniert ganz gut ... Ich weiß nicht, was ich damals gedacht habe ... Eigentlich ist seine Lösung besser als meine, denke ich ...
dertoni
1

Ich habe im letzten Jahr über diesen Immobilienrahmen geschrieben. Es bietet mehrere Möglichkeiten, Eigenschaften zu laden und sie auch stark zu tippen.

Schauen Sie sich http://sourceforge.net/projects/jhpropertiestyp/ an.

JHPropertiesTyped gibt dem Entwickler stark typisierte Eigenschaften. Einfache Integration in bestehende Projekte. Wird von einer großen Serie für Eigenschaftstypen behandelt. Ermöglicht die einzeilige Initialisierung von Eigenschaften über Eigenschafts-E / A-Implementierungen. Ermöglicht dem Entwickler die Erstellung eigener Eigenschaftstypen und Eigenschafts-IOs. Web-Demo ist ebenfalls verfügbar, Screenshots oben gezeigt. Verfügen Sie auch über eine Standardimplementierung für ein Web-Front-End zum Verwalten von Eigenschaften, wenn Sie diese verwenden möchten.

Eine vollständige Dokumentation, ein Tutorial, Javadoc, FAQ usw. finden Sie auf der Projektwebseite.

FrederikH
quelle
0

Hier bereit statische Klasse

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

Hier Beispiel:

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

Sie können die Eigenschaftendatei wie folgt laden:

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

Und dann können Sie mit einem Lambda-Ausdruck wie folgt über die Karte iterieren:

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

Meiner Meinung nach sind andere Möglichkeiten veraltet, wenn wir es wie folgt ganz einfach machen können:

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

    @Autowired
    private Environment env;

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

}

es ist so einfach, aber ich denke das ist der beste Weg !! Genießen

Sobhan
quelle