Как использовать файлы свойств Java?


219

У меня есть список пар ключ / значение значений конфигурации, которые я хочу сохранить в виде файлов свойств Java, а затем загрузить и выполнить итерацию.

Вопросы:

  • Нужно ли хранить файл в том же пакете, что и класс, который будет их загружать, или есть какое-то конкретное место, где он должен быть размещен?
  • Должен ли файл заканчиваться каким-либо конкретным расширением или все в .txtпорядке?
  • Как я могу загрузить файл в коде
  • И как я могу перебрать значения внутри?

Ответы:


246

Вы можете передать InputStream в Property, чтобы ваш файл мог находиться где угодно и вызываться как угодно.

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

Какое значение возвращается, когда ключ отсутствует в файле свойств?
Митакш Гупта

2
@MitakshGupta Если свойство с именем, которое вы передали, не найдено ни в файле, ни в списке свойств по умолчанию, оно возвращается null. См. Javadoc
drigoangelo

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

80
  • Вы можете хранить файл где угодно. Если вы хотите сохранить его в своем JAR-файле, вы захотите использовать его Class.getResourceAsStream()или ClassLoader.getResourceAsStream()получить к нему доступ. Если это в файловой системе, это немного проще.

  • Любое расширение в порядке, хотя .properties чаще встречается в моем опыте

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

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


1
Спасибо Джон, в следующий раз я узнаю кое-что о Джоде, и ты тоже ответишь.
Пламя

27

Если вы поместите файл свойств в тот же пакет, что и класс Foo, вы можете легко загрузить его с помощью

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

Учитывая, что Properties расширяет Hashtable, вы можете перебирать значения таким же образом, как и в Hashtable.

Если вы используете расширение * .properties, вы можете получить поддержку редактора, например, Eclipse имеет редактор файлов свойств.


5
Вы можете сделать это, но мне не нравится хранить файлы свойств в одном пакете. В итоге вы получите файлы свойств, распределенные по всему приложению. Я бы предпочел хранить все файлы свойств в корне приложения и загружать их как "class.getResourceAsStream (" \ file.properties ")" или в каком-либо другом известном месте.
Nate

Нейт, это правда. Тем не менее, в некоторых сценариях развернутое местоположение неизвестно (например, все ваши компоненты включены в некоторый архив). В таких случаях может быть довольно удобно сказать «это с этим классом, где бы он ни находился». Также, чтобы не распространять файлы по всему, для всех файлов свойств можно использовать один пакет конфигурации.
Фабиан Стиг

1
Фабиан, оба этих случая работают с моим комментарием - он основан на пути к классам, а не на файловой системе.
Nate

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? пожалуйста, помогите мне.
Атиш Шимпи

@atishshimpi Не требуется при работе с типом Properties, но является обязательным для 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, если вы не хотите.


Однако некоторые «расширения» файлов свойств предполагают расширение .properties - например, ResourceBundle, используемый в I18N.
Nate

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

Что делать, если у вас есть 3 файла proprties?
Анджелина

4

Свойства стали наследием. Предпочтения класса предпочтительнее свойства.

Узел в иерархической коллекции данных о предпочтениях. Этот класс позволяет приложениям хранить и извлекать пользовательские и системные предпочтения и данные конфигурации. Эти данные постоянно хранятся в зависимом от реализации резервном хранилище. Типичные реализации включают в себя плоские файлы, специфичные для ОС реестры, серверы каталогов и базы данных SQL. Пользователю этого класса не нужно беспокоиться о деталях бэк-магазина.

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

  1. строка
  2. логический
  3. двойной
  4. поплавок
  5. ИНТ
  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. Montecristo уже показано , как загрузить это. Это должно работать нормально.
  4. propertyNames () дает вам перечисление для перебора.

2. no extension is necessaryМожете ли вы дать мне любую ссылку для этого заявления, пожалуйста. Я путаюсь с этим.
Атиш Шимпи

Обратите внимание, что вы можете загрузить свойства через входной поток. Таким образом, свойства не знают, откуда поступил этот входной поток (файл? Сокет?), И, следовательно, не могут применять стандарт именования
Брайан Агнью,

3

По умолчанию Java открывает его в рабочем каталоге вашего приложения (это поведение зависит от используемой ОС). Чтобы загрузить файл, выполните:

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

Таким образом, любое расширение файла может быть использовано для файла свойств. Кроме того, файл также может храниться где угодно, если вы можете использоватьFileInputStream .

Если вы используете современную платформу, она может предоставить дополнительные способы открытия файла свойств. Например, Spring предоставляет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
Мне очень жаль Я рассмотрел код в ответе Зеда, и он работает довольно хорошо ... Я не знаю, что я тогда думал ... На самом деле его решение лучше, чем мое, я думаю ...
dertoni

1

Я написал об этой структуре собственности за последний год. Это обеспечит несколько способов загрузки свойств, а также их строгую типизацию.

Посмотрите на http://sourceforge.net/projects/jhpropertiestyp/

JHPropertiesTyped предоставит разработчику строго типизированные свойства. Легко интегрировать в существующие проекты. Обрабатывается большой серией для типов свойств. Предоставляет возможность инициализации свойств в одну строку с помощью реализаций ввода-вывода свойств. Дает разработчику возможность создавать собственные типы свойств и свойства io's. Веб-демо также доступна, скриншоты показаны выше. Также есть стандартная реализация веб-интерфейса для управления свойствами, если вы решите использовать его.

Полная документация, учебник, 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.