Як користуватися файлами властивостей Java?


219

У мене є список пар ключів / значень значень конфігурації, які я хочу зберігати як файли властивостей Java, а пізніше завантажувати і повторювати.

Запитання:

  • Чи потрібно мені зберігати файл у тому ж пакеті, що і клас, який буде завантажувати їх, чи є якесь певне місце, де його слід розмістити?
  • Чи потрібно закінчувати файл у будь-якому конкретному розширенні чи це .txtнормально?
  • Як я можу завантажити файл у код
  • І як я можу повторити значення всередині?

Відповіді:


246

Ви можете передати InputStream до властивості, тому ваш файл може бути майже в будь-якому місці та викликати що завгодно.

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

Повторити як:

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

Яке значення повертається, коли ключ не присутній у файлі властивостей?
Mitaksh Gupta

2
@MitakshGupta Якщо властивість з іменем, яке ви передали, не знайдено у файлі чи у списку властивостей за замовчуванням, воно відновиться null. Дивіться Javadoc
drigoangelo

3
як це порівнюється з properties.load(PropertiesReader.class.getResourceAsStream("/properties.properties")); цим, getResourceAsStreamпорівняно FileInputStream? плюси і мінуси?
Туфір

80
  • Ви можете зберігати файл де завгодно. Якщо ви хочете зберегти його у вашому файлі jar, ви хочете скористатися ним Class.getResourceAsStream()або ClassLoader.getResourceAsStream()отримати доступ до нього. Якщо це у файловій системі, це трохи простіше.

  • Будь-яке розширення чудово, хоча .властивості є більш поширеними в моєму досвіді

  • Завантажте файл , використовуючи Properties.load, що переходить в InputStreamабо StreamReaderякщо ви використовуєте Java 6. (Якщо будуть з допомогою Java 6, я б , ймовірно , використовувати UTF-8 , і Readerзамість того , щоб за замовчуванням ISO-8859-1 кодування для потоку. )

  • Ітерайте через нього так, як ви повторите його через звичайне Hashtable(що Propertiesпоходить від), наприклад, використовуючи keySet(). Крім того, ви можете використовувати перерахування, повернені користувачем propertyNames().


1
Дякую, Джон, наступне, що я знаю, що я шукаю щось на joda, і ти відповідеш теж на це.
Полум’я

27

Якщо ви розмістите файл властивостей у тому ж пакеті, що і клас Foo, ви можете легко завантажити його

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

Зважаючи на те, що властивості поширюються Hashtable, ви можете перебирати значення таким же чином, як і в Hashtable.

Якщо ви використовуєте розширення * .properties, ви можете отримати підтримку редактора, наприклад, Eclipse має редактор файлів властивостей.


5
Ви можете це зробити, але мені не подобається зберігання файлів властивостей в одному пакеті. У кінцевому підсумку файли властивостей поширюються по всьому місцю програми. Я набагато краще зберігати всі файли властивостей у корені програми та завантажувати їх як "class.getResourceAsStream (" \ file.properties ")" або в іншому відомому місці.
Нейт

Нейт, це правда. Однак у деяких сценаріях розгорнуте місце розташування невідоме (наприклад, всі ваші конкретні компоненти вбудовані в якийсь архів). У таких випадках може бути досить зручно сказати: "це з тим класом, де б не закінчився цей клас". Щоб уникнути поширення файлів по всьому світу, для всіх файлів властивостей може використовуватися один конфігураційний пакет.
Фабіан Стіг

1
Фабіан, обидва ці випадки працюють з моїм коментарем - він заснований на classpath - а не на файловій системі.
Нейт

2
Для тих, хто намагається змусити приклад Нейт працювати - зворотний косий слід замінити косою нахилом. Тож у цьому випадку: 'class.getResourceAsStream ("/ file.properties")'
hash_collision

12

Існує багато способів створення та читання propertiesфайлів:

  1. Зберігайте файл у тому ж пакеті.
  2. .propertiesОднак рекомендуйте розширення, але ви можете вибрати власне.
  3. Використовуйте тези класів , розташованих в java.utilпакеті => Properties, ListResourceBundle, ResourceBundleкласи.
  4. Для читання властивостей використовуйте ітератор або перелічувач або прямі методи класу Propertiesабо java.lang.Systemкласу.

ResourceBundle клас:

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

Properties клас:

Properties ps = new Properties();
ps.Load(new java.io.FileInputStream("my.properties"));

Привіт AVD, чому нам потрібне .propertiesлише розширення? що не так із розширенням '.txt'? будь ласка, допоможіть мені.
atish shimpi

@atishshimpi Не потрібно при роботі з типом властивості , але він є обов'язковим для ResourceBundle - читати doc- docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html
adatapost

5

Це завантажує файл властивостей:

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

Я використовую, щоб розмістити файл .properties в каталозі, де я маю всі файли конфігурації, я не ставлю його разом із класом, який отримує доступ до нього, але тут немає обмежень.

Для імені ... Я використовую .properties заради багатослівності, я не думаю, що ви повинні називати це. Властивостями, якщо ви не хочете.


Однак деякі "розширення" файлів властивостей припускають розширення .properties - наприклад, ResourceBundle, що використовується в I18N.
Нейт

5

Приклад:

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

що робити, якщо у вас є три файли пропрітей?
Анджеліна

4

Властивості перейшли у спадщину. Клас переваг віддають перевагу властивостям.

Вузол в ієрархічній колекції даних уподобань. Цей клас дозволяє програмам зберігати та отримувати дані про налаштування користувачів та системи та налаштування. Ці дані постійно зберігаються в резервному сховищі, залежному від реалізації. Типові реалізації включають плоскі файли, специфічні для ОС реєстри, сервери каталогів і бази даних SQL. Користувач цього класу не повинен перейматися деталями магазину резервної копії.

На відміну від властивостей, які є на основі рядків пар ключ-значення, Preferencesклас має кілька методів, які використовуються для отримання та розміщення примітивних даних у сховищі даних Preferences. Ми можемо використовувати лише такі типи даних:

  1. Рядок
  2. булева
  3. подвійний
  4. плавати
  5. int
  6. довго
  7. байтовий масив

Щоб завантажити файл властивостей, ви можете надати абсолютний шлях або використовувати, getResourceAsStream()якщо файл властивостей присутній у вашому класі.

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-файл:

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

Погляньте на цю статтю про внутрішні магазини налаштувань


3

В порядку:

  1. Ви можете зберігати файл у будь-якому місці.
  2. розширення не потрібно.
  3. Монтекрісто проілюстрував, як це завантажити. Це повинно працювати добре.
  4. propertyNames () дає перерахування для повторення.

2. no extension is necessary, Чи можете ви, будь ласка, надати мені будь-яку посилання на цю заяву, будь ласка. Я маю плутанину з цього приводу.
atish shimpi

Зверніть увагу, що ви можете завантажити властивості за допомогою вхідного потоку. Оскільки такі властивості не знають, звідки взявся цей вхідний потік (файл? Socket?), І, отже, не можна застосувати стандарт іменування
Brian Agnew

3

За замовчуванням Java відкриває його в робочому каталозі вашої програми (ця поведінка фактично залежить від використовуваної ОС). Щоб завантажити файл, виконайте:

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

Таким чином, будь-яке розширення файлу може використовуватися для файлу властивостей. Крім того, файл також можна зберігати в будь-якому місці, якщо ви можете використовувати FileInputStream.

У відповідній примітці, якщо ви використовуєте сучасний фреймворк, фреймворк може містити додаткові способи відкриття файлу властивостей. Наприклад, Spring надає a ClassPathResourceдля завантаження файла властивості, використовуючи ім'я пакета зсередини файлу JAR.

Що стосується ітерації через властивості, після завантаження властивостей вони зберігаються в java.util.Propertiesоб'єкті, який пропонує propertyNames()метод.


3

Читання файлу властивостей та завантаження його вмісту в Properties

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

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

Нижче наведено ефективний спосіб ітерації над Properties

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

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

3

В Java 8, щоб отримати всі свої властивості

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) Добре мати свій файл власності на classpath, але ви можете розмістити його в будь-якому місці проекту.

Нижче описано, як ви завантажуєте файл властивостей з classpath та читаєте всі властивості.

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) Файли властивостей мають розширення як .properties


1

Ось ще один спосіб перебрати властивості:

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

2
Мені абсолютно шкода. Я переглянув код у відповіді Зеда, і він працює досить добре ... Я не знаю, що я тоді думав ... Насправді його рішення є кращим, ніж моє, я думаю ...
дертоні

1

Я писав про цю власність протягом останнього року. Він надасть декілька способів завантаження властивостей, а також їх сильно набрані.

Погляньте на http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped надасть розробнику сильно набрані властивості. Легко інтегруватись у існуючі проекти. Обробляється великою серією для типів властивостей. Надає можливість однорядкової ініціалізації властивостей через реалізацію IO властивості. Дає розробнику можливість створювати власні типи властивостей та властивості io. Також доступна веб-демонстрація, скріншоти, показані вище. Також ви маєте стандартну реалізацію для переднього веб-сторінки, щоб керувати властивостями, якщо ви вирішили ним користуватися.

Повна документація, підручник, javadoc, faq тощо доступні на веб-сторінці проекту.


0

Тут готовий статичний клас

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

Ось зразок:

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

Ви можете завантажити файл властивостей у такий спосіб:

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

І тоді ви можете переглядати карту за допомогою лямбда-виразу:

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

0

на мою думку, інші способи застаріли, коли ми можемо зробити це дуже просто, як нижче:

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

    @Autowired
    private Environment env;

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

}

це так просто, але я думаю, що це найкращий спосіб !! Насолоджуйтесь

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.