Jak korzystać z plików właściwości Java?

219

Mam listę par klucz / wartość wartości konfiguracyjnych, które chcę przechowywać jako pliki właściwości Java, a następnie ładować i iterować.

Pytania:

  • Czy muszę przechowywać plik w tym samym pakiecie co klasa, która je załaduje, czy może jest jakieś konkretne miejsce, w którym powinien zostać umieszczony?
  • Czy plik musi kończyć się konkretnym rozszerzeniem, czy jest w .txtporządku?
  • Jak mogę załadować plik do kodu?
  • Jak mogę iterować wartości w środku?
Kliknij opcję Upvote
źródło

Odpowiedzi:

245

Możesz przekazać InputStream do właściwości, dzięki czemu plik może znajdować się w dowolnym miejscu i wywołać dowolną nazwę.

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

Iteruj jako:

for(String key : properties.stringPropertyNames()) {
  String value = properties.getProperty(key);
  System.out.println(key + " => " + value);
}
Zed
źródło
Jaka wartość jest zwracana, gdy klucz nie występuje w pliku właściwości?
Mitaksh Gupta
2
@MitakshGupta Jeśli właściwość o podanej nazwie nie zostanie znaleziona w pliku lub na domyślnej liście właściwości, nastąpi ponowna próba null. Zobacz Javadoc
drigoangelo
3
jak to porównać properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); to jest getResourceAsStreamkontra FileInputStream? plusy i minusy?
Thufir
80
  • Ty można zapisać do pliku w dowolnym miejscu. Jeśli chcesz zachować go w pliku jar, będziesz chciał go użyć Class.getResourceAsStream()lub ClassLoader.getResourceAsStream()uzyskać do niego dostęp. Jeśli jest w systemie plików, jest to nieco łatwiejsze.

  • Każde rozszerzenie jest w porządku, chociaż .properties jest bardziej powszechne z mojego doświadczenia

  • Załaduj plik, używając Properties.load, przechodząc w sposób InputStreamlub StreamReaderjeśli używasz Java 6. (Jeśli za pomocą Java 6, ja pewnie używać UTF-8, a Readerzamiast domyślnego kodowania ISO-8859-1 dla strumienia. )

  • Iteruj przez to tak, jak iterujesz przez normalny Hashtable(który Propertiespochodzi od), np keySet(). Używając . Alternatywnie możesz użyć wyliczenia zwróconego przez propertyNames().

Jon Skeet
źródło
1
Dzięki Jon, następną rzeczą, o której wiem, będę szukał czegoś na temat Jody, a ty również odpowiesz.
Płomień
27

Jeśli umieścisz plik właściwości w tym samym pakiecie co klasa Foo, możesz go łatwo załadować

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

Biorąc pod uwagę, że Właściwości rozszerza Hashtable, możesz iterować wartości w taki sam sposób, jak w Hashtable.

Jeśli używasz rozszerzenia * .properties, możesz uzyskać obsługę edytora, np. Eclipse ma edytor plików właściwości.

Fabian Steeg
źródło
5
Możesz to zrobić - ale nie lubię przechowywania plików właściwości w tym samym pakiecie. Skończysz z plikami właściwości rozrzuconymi po całym miejscu w aplikacji. Wolałbym przechowywać wszystkie pliki właściwości w katalogu głównym aplikacji i ładować je jako „class.getResourceAsStream („ \ file.properties ”)” lub w innej znanej lokalizacji.
Nate
Nate, to prawda. Jednak w niektórych scenariuszach wdrożona lokalizacja nie jest znana (np. Wszystko z konkretnego komponentu jest spakowane w jakieś archiwum). W takich przypadkach może być całkiem wygodne powiedzenie „jest z tą klasą, gdziekolwiek ta klasa się skończy”. Aby uniknąć rozprzestrzeniania się plików na cały plik, do wszystkich plików właściwości można użyć jednego pakietu konfiguracji.
Fabian Steeg
1
Fabian, oba te przypadki działają z moim komentarzem - jest oparty na ścieżce klas - nie na systemie plików.
Nate
2
Dla każdego, kto próbuje sprawić, by przykład Nate'a zadziałał - odwrotny ukośnik należy zastąpić ukośnikiem. Więc w tym przypadku: „class.getResourceAsStream („ / file.properties ”)”
hash_collision
12

Istnieje wiele sposobów tworzenia i odczytywania propertiesplików:

  1. Zapisz plik w tym samym pakiecie.
  2. Polecam .propertiesrozszerzenie, jednak możesz wybrać własne.
  3. Zastosowanie tez klas znajdujące się w java.utilopakowaniu => Properties, ListResourceBundle, ResourceBundlezajęcia.
  4. Aby odczytać właściwości, użyj iteratora lub modułu wyliczającego lub bezpośrednich metod Propertieslub java.lang.Systemklasy.

ResourceBundle klasa:

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

Properties klasa:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));
adatapost
źródło
Cześć AVD, dlaczego potrzebujemy .propertiestylko rozszerzenia? co jest nie tak z rozszerzeniem „.txt”? proszę mi pomóc.
atish shimpi
@atishshimpi Nie jest wymagane podczas pracy z typem właściwości, ale jest obowiązkowe dla ResourceBundle - przeczytaj doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost
5

Spowoduje to załadowanie pliku właściwości:

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

Używam, aby umieścić plik .properties w katalogu, w którym mam wszystkie pliki konfiguracyjne, nie łączę go z klasą, która ma do niego dostęp, ale tutaj nie ma żadnych ograniczeń.

Na imię ... używam .properties ze względu na gadatliwość, nie sądzę, że powinieneś nazywać go .properties, jeśli nie chcesz.

Alberto Zaccagni
źródło
Jednak niektóre „rozszerzenia” plików właściwości zakładają rozszerzenie .properties - na przykład ResourceBundle używany w I18N.
Nate
5

Przykład:

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
źródło
co jeśli masz 3 pliki własności?
Angelina,
4

Właściwości stały się dziedzictwem. Klasa preferencji jest lepsza od właściwości.

Węzeł w hierarchicznym zbiorze danych preferencji. Ta klasa umożliwia aplikacjom przechowywanie i pobieranie preferencji użytkownika i systemu oraz danych konfiguracyjnych. Te dane są przechowywane trwale w magazynie kopii zapasowych zależnym od implementacji. Typowe implementacje obejmują pliki płaskie, rejestry specyficzne dla systemu operacyjnego, serwery katalogów i bazy danych SQL. Użytkownik tej klasy nie musi martwić się szczegółami sklepu z podkładami.

W przeciwieństwie do właściwości, które są parami klucz-wartość opartymi na łańcuchach, Preferencesklasa ma kilka metod używanych do pobierania i umieszczania prymitywnych danych w magazynie danych Preferencje. Możemy korzystać tylko z następujących rodzajów danych:

  1. Strunowy
  2. boolean
  3. podwójnie
  4. pływak
  5. int
  6. długie
  7. tablica bajtów

Aby załadować plik właściwości, możesz podać ścieżkę bezwzględną lub użyć, getResourceAsStream()jeśli plik właściwości znajduje się w ścieżce klasy.

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

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

Zapoznaj się z tym artykułem na temat wnętrza sklepu preferencji

Ravindra babu
źródło
3

W celu:

  1. Możesz przechowywać plik w dowolnym miejscu.
  2. przedłużenie nie jest konieczne.
  3. Montecristo zilustrował sposób ładowania tego. To powinno działać dobrze.
  4. propertyNames () daje ci wyliczenie do iteracji.
Brian Agnew
źródło
2. no extension is necessary, Czy możesz podać mi wszelkie odniesienia do tego oświadczenia, proszę. Mam co do tego zamieszanie.
atish shimpi
Pamiętaj, że możesz załadować właściwości za pośrednictwem strumienia wejściowego. W związku z tym właściwości nie mają wiedzy o tym, skąd pochodzi ten strumień wejściowy (plik? Gniazdo?), W związku z czym nie mogą egzekwować standardu nazewnictwa
Brian Agnew
3

Domyślnie Java otwiera go w katalogu roboczym aplikacji (takie zachowanie faktycznie zależy od używanego systemu operacyjnego). Aby załadować plik, wykonaj:

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

Jako takie, do pliku właściwości można użyć dowolnego rozszerzenia pliku. Ponadto plik można również przechowywać w dowolnym miejscu, o ile można użyć pliku FileInputStream.

W pokrewnej uwadze, jeśli używasz nowoczesnego frameworka, frameworka może zapewnić dodatkowe sposoby otwierania pliku właściwości. Na przykład Spring zapewnia ClassPathResourceładowanie pliku właściwości przy użyciu nazwy pakietu z pliku JAR.

Jeśli chodzi o iterację po właściwościach, po załadowaniu właściwości są one przechowywane w java.util.Propertiesobiekcie, który oferuje tę propertyNames()metodę.

Thierry-Dimitri Roy
źródło
3

Odczytywanie pliku właściwości i ładowanie jego zawartości do Properties

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

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

Poniżej przedstawiono skuteczny sposób na iterację po Properties

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

        System.out.println(entry.getKey() + " => " + entry.getValue());
    }
JoBⅈN
źródło
3

W Javie 8, aby uzyskać wszystkie swoje właściwości

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
źródło
2

1) Dobrze jest mieć plik właściwości w ścieżce klasy, ale możesz go umieścić w dowolnym miejscu w projekcie.

Poniżej znajduje się sposób ładowania pliku właściwości ze ścieżki klasy i odczytywania wszystkich właściwości.

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) Pliki właściwości mają rozszerzenie jako .properties

Jitender Chahar
źródło
1

Oto inny sposób na iterację właściwości:

Enumeration eProps = properties.propertyNames();
while (eProps.hasMoreElements()) { 
    String key = (String) eProps.nextElement(); 
    String value = properties.getProperty(key); 
    System.out.println(key + " => " + value); 
}
dertoni
źródło
2
Jest mi absolutnie przykro Przejrzałem kod w odpowiedzi Zeda i działa całkiem dobrze ... Nie wiem, co wtedy wtedy myślałem ... Właściwie jego rozwiązanie jest lepsze niż moje, tak myślę ...
dertoni
1

Pisałem o tej strukturze własności z ostatniego roku. Zapewni wiele sposobów ładowania właściwości, a także silnego ich typowania.

Zajrzyj na http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped nada deweloperowi silnie typowane właściwości. Łatwa do zintegrowania z istniejącymi projektami. Obsługiwane przez dużą serię dla typów nieruchomości. Daje możliwość inicjowania właściwości w jednym wierszu za pośrednictwem implementacji IO właściwości. Daje deweloperowi możliwość tworzenia własnych typów i właściwości nieruchomości. Dostępne jest również demo internetowe, powyższe zrzuty ekranu. Posiadaj również standardową implementację interfejsu WWW do zarządzania właściwościami, jeśli zdecydujesz się z niego korzystać.

Pełna dokumentacja, samouczek, javadoc, FAQ itp. Jest dostępna na stronie projektu.

FrederikH
źródło
0

Tutaj gotowa klasa statyczna

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

Oto próbka:

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
źródło
0

Plik właściwości można załadować w następujący sposób:

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

Następnie możesz iterować mapę, używając wyrażenia lambda, takiego jak:

props.stringPropertyNames().forEach(key -> {
            System.out.println("Key is :"+key + " and Value is :"+props.getProperty(key));
        });
Piyush Dash
źródło
0

moim zdaniem inne sposoby są przestarzałe, kiedy możemy to zrobić bardzo prosto, jak poniżej:

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

    @Autowired
    private Environment env;

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

}

to takie proste, ale myślę, że to najlepszy sposób !! Cieszyć się

Sobhan
źródło