Перейти к контенту

Примеры работы с Java Properties

Большинству программ Java в какой-то момент необходимо использовать свойства, как правило, для хранения простых параметров в виде пар ключ-значение вне скомпилированного кода.

Таким образом, язык имеет поддержку класса для свойств — java.util.Properties — служебный класс, предназначенный для обработки файлов конфигурации этого типа.

 

В этой статье я покажу использование базового класса Properties, в том числе способы загрузки и сохранения в формате XML, как управлять парами ключ-значение в объекте свойств, например извлекать значения, обновлять, получить его размер и как использовать список по умолчанию для объекта.

  • Properties является подклассом Hashtable. Он используется для ведения списков значений, в которых ключ является строкой, а значение также является строкой.
  • Класс Properties используется многими другими классами Java. Например, это тип объекта, возвращаемый System.getProperties() при получении значений.
  • Одна полезная возможность класса состоит в том, что вы можете указать свойство по умолчанию, которое будет возвращаться, если никакое значение не связано с определенным ключом.
  • Несколько потоков могут совместно использовать один объект без необходимости внешней синхронизации.
  • Properties определяет переменную экземпляра.
  • Properties() создает объект Properties, который не имеет значений по умолчанию.
  • Properties (Properties propDefault): второй создает объект, который использует propDefault в качестве значения по умолчанию.
Метод и описание
1String getProperty (String key) Возвращает значение, связанное с ключом. Пустой объект возвращается, если ключ отсутствует в списке или в списке свойств по умолчанию.
2String getProperty (String key, String defaultProperty) возвращает значение, связанное с ключом; defaultProperty возвращается, если ключ не находится ни в списке, ни в списке свойств по умолчанию.
3void list (PrintStream streamOut) Отправляет список свойств в выходной поток, связанный с streamOut.
4void list (PrintWriter streamOut) Отправляет список свойств в выходной поток, связанный с streamOut.
5void load (InputStream streamIn) throws IOException Вводит список свойств из входного потока, связанного с streamIn.
6Перечисление propertyNames() Возвращает перечисление ключей. Сюда входят также ключи, найденные в списке свойств по умолчанию.
7Объект setProperty (String key, String value) Связывает значение с ключом. Возвращает предыдущее значение, связанное с ключом, или возвращает null, если такой ассоциации не существует.
8void store (OutputStream streamOut, String description) После записи строки, указанной в описании, список свойств записывается в выходной поток, связанный с streamOut.

Начнем с примера загрузки пар ключ-значение из файлов свойств; мы загружаем два файла, которые мы имеем в нашем classpath:

app.properties:

version=1.0
name=TestApp
date=2016-11-12

И catalog:

c1=files
c2=images
c3=videos

Обратите внимание, что в файлах свойств рекомендуется использовать «.properties», в suffix это не обязательно.

Теперь мы можем очень просто загрузить их в экземпляр Properties:

String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String appConfigPath = rootPath + "app.properties";
String catalogConfigPath = rootPath + "catalog";
 
Properties appProps = new Properties();
appProps.load(new FileInputStream(appConfigPath));
 
Properties catalogProps = new Properties();
catalogProps.load(new FileInputStream(catalogConfigPath));
 
   
String appVersion = appProps.getProperty("version");
assertEquals("1.0", appVersion);
         
assertEquals("files", catalogProps.getProperty("c1"));

Если содержимое файла соответствует требованиям формата файла свойств, оно может быть правильно проанализировано классом Properties.

Загрузка из файлов XML

Помимо файлов, класс Properties также может загружать файлы XML, которые соответствуют определенным спецификациям DTD.

Вот пример для загрузки пар ключ-значение из файла XML — icons.xml:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>xml example</comment>
    <entry key="fileIcon">icon1.jpg <entry>
    <entry key="imageIcon">icon2.jpg <entry>
    <entry key="videoIcon">icon3.jpg <entry>
</properties>

Теперь давайте загрузим:

String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
String iconConfigPath = rootPath + "icons.xml";
Properties iconProps = new Properties();
iconProps.loadFromXML(new FileInputStream(iconConfigPath));
 
assertEquals("icon1.jpg", iconProps.getProperty("fileIcon"));

Как получить свойства?

Мы можем использовать getProperty (ключ String) и getProperty (ключ String, String defaultValue), чтобы получить значение по его ключу.

Если пара ключ-значение существует, оба метода будут возвращать соответствующее значение. Но если такой пары ключ-значение не существует, первая вернет null, а вторая вместо нее вернет defaultValue.

Пример кода:

String appVersion = appProps.getProperty("version");
String appName = appProps.getProperty("name", "defaultName");
String appGroup = appProps.getProperty("group", "baeldung");
String appDownloadAddr = appProps.getProperty("downloadAddr");
 
assertEquals("1.0", appVersion);
assertEquals("TestApp", appName);
assertEquals("baeldung", appGroup);
assertNull(appDownloadAddr);

Обратите внимание, что хотя класс Properties наследует метод get() от класса Hashtable, я не рекомендую использовать его для получения значения. Поскольку его метод get() будет возвращать значение Object, которое может быть приведено только к String, а метод getProperty() уже обрабатывает значение Object правильно.

Код ниже выдаст исключение:
float appVerFloat = (float) appProps.get("version");

Как установить свойства

Мы можем использовать метод setProperty(), чтобы обновить существующую пару ключ-значение или добавить новую.

Пример:

appProps.setProperty("name", "NewAppName"); // обновить старое значение
appProps.setProperty("downloadAddr", "www.baeldung.com/downloads"); // добавить новую пару ключ-значение
 
String newAppName = appProps.getProperty("name");
assertEquals("NewAppName", newAppName);
         
String newAppDownloadAddr = appProps.getProperty("downloadAddr");
assertEquals("www.baeldung.com/downloads", newAppDownloadAddr);

Класс Properties наследует метод put() и метод putAll() от класса Hashtable, я не рекомендую использовать их по той же причине, что и для метода get(): в свойствах могут использоваться только строковые значения.

Приведенный ниже код не будет работать так, как вы хотите, когда вы используете getProperty() для получения его значения, он вернет null:
appProps.put("version", 2);

Удалить свойства

Если вы хотите удалить пару ключ-значение, вы можете использовать метод remove().

String versionBeforeRemoval = appProps.getProperty("version");
assertEquals("1.0", versionBeforeRemoval);
 
appProps.remove("version");    
String versionAfterRemoval = appProps.getProperty("version");
assertNull(versionAfterRemoval);

Хранение Properties

Класс Properties предоставляет метод store() для вывода пар ключ-значение.

String newAppConfigPropertiesFile = rootPath + "newApp.properties";
appProps.store(new FileWriter(newAppConfigPropertiesFile), "store to properties file");

Второй параметр используется для комментариев. Если вы не хотите писать какой-либо комментарий, просто используйте для него значение null.

Хранение в XML-файлах

Класс Properties также предоставляет метод storeToXML() для вывода пар ключ-значение в формате XML.

String newAppConfigXmlFile = rootPath + "newApp.xml";
appProps.storeToXML(new FileOutputStream(newAppConfigXmlFile), "store to xml file");

Второй параметр такой же, как и в методе store().

Объект Properties может содержать другой объект Properties в качестве списка свойств по умолчанию. Список свойств по умолчанию будет найден, если ключ свойства не найден в исходном.

Помимо «app.properties», у нас есть еще один файл — «default.properties» — в classpath:

site=www.google.com
name=DefaultAppName
topic=Properties
category=core-java
String rootPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
 
String defaultConfigPath = rootPath + "default.properties";
Properties defaultProps = new Properties();
defaultProps.load(new FileInputStream(defaultConfigPath));
 
String appConfigPath = rootPath + "app.properties";
Properties appProps = new Properties(defaultProps);
appProps.load(new FileInputStream(appConfigPath));
 
assertEquals("1.0", appVersion);
assertEquals("TestApp", appName);
assertEquals("www.google.com", defaultSite);

По умолчанию файлы свойств должны быть в кодировке ISO-8859-1 (Latin-1), поэтому обычно не следует использовать свойства с символами не из ISO-8859-1.

Мы можем обойти это ограничение с помощью таких инструментов, как JDK native2ascii или явное кодирование файлов, если это необходимо. Для файлов XML метод loadFromXML() и метод storeToXML() по умолчанию используют кодировку UTF-8.

Однако при чтении XML-файла, закодированного по-другому, мы можем указать это в объявлении DOCTYPE; запись также достаточно гибкая — мы можем указать кодировку в третьем параметре API storeToXML().

Полный исходный код проекта доступен на GitHub

Оцени статью

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим - напишите комментарий, добавьте информации к статье.

Или поделись статьей

Видим, что вы не нашли ответ на свой вопрос.

Помогите улучшить статью.

 

Пока нет комментариев.

Добавить комментарий

Ваш e-mail не будет опубликован.

СайдбарКомментарии (0)