Property file java android

Чтение конфигурационных файлов в Java: nProperty


Многие разработчики сталкиваются с необходимостью чтения конфигурационных (*.ini, *.prop, *.conf, etc.) файлов в разрабатываемых приложениях. В Java есть стандартный класс Properties, с помощью которого можно очень легко загрузить ini-файл и прочитать его свойства. При большом объеме конфигурационных файлов чтение и запись настроек в объекты превращается в очень нудную и рутинную работу: создать объект Properties, конвертировать каждую настройку в нужный формат и записать его в поле.

Библиотека nProperty (Annotated Property) призвана упростить этот процесс, сократив примерно в два раза требуемый код для написания загрузчиков настроек.

Чтобы показать, каким образом возможно обещанное сокращение кода в два раза, ниже приведены два примера: в первом примере используется стандартный класс Properties, во-втором — nProperty.

Статья и сама библиотека nProperty написана моим другом и товарищем по цеху Yorie для внутрикомандных повседневных нужд, и так как он, к сожалению, не имеет в данный момент инвайта на хабре, я взял на себя смелость, с его согласия, опубликовать сие творение для «хабровских» масс.

Содержание

Просто о главном

В обоих примерах будет использован один и тот же файл конфигурации:

Пример №1. Загрузка конфигурации с помощью стандартного класса Properties.

Пример №2. Загрузка конфигурации с помощью nProperty.

Пожалуй, из этих красивых примеров вытекает факт, что код может быть сокращен даже более, чем в два раза 🙂 В этих примерах не освещены темы присутствия в полях классов переменных, не относящихся к файлам конфигурации, а также еще несколько тонких нюансов. Но обо всем по порядку.

Чтение примитивных и стандартных типов

Во втором вышеприведенном примере стоит обратить внимание на аннотацию @Сfg. Она и является причиной сократившегося кода. Библиотека nProperty основана на аннотациях, которые могут быть применены к классам, полям и методам классов.

Чтобы прочитать из конфигурационного файла настройки, тип которых относится к примитивным, достаточно каждое поле класса обозначить аннотацией @Сfg:

Библиотека nProperty поддерживает достаточно богатый набор стандартных типов:

  • Integer/int
  • Short/short
  • Double/double
  • Long/long
  • Boolean/boolean
  • String
  • Character/char
  • Byte/byte
  • AtomicInteger, AtomicLong, AtomicBoolean
  • BigInteger, BigDecimal

Все эти перечисленные типы могут быть использованы в примере выше.

Десериализация в массивы и коллекции

Помимо стандартных типов также возможна десериализация в массивы с одним условием — тип массива должен принадлежать множеству стандартных типов:

В случае с массивами библиотека сама позаботится о том, чтобы проинициализировать массив нужного размера.

Обратите внимание на аннотации у SOME_INT_ARRAY и SOME_SHORT_ARRAY. По умолчанию nProperty использует в качестве разделителя символ «;». Его можно легко переопределить, указав в аннотации к полю свойство splitter. И, как можно заметить, разделителем может выступать полноценное регулярное выражение.

Помимо массивов возможно использование коллекций, а именно — списков. Здесь необходимым является одно условие — коллекция должна быть обязательно проинициализирована до запуска чтения конфигурации. Это связано с тем, что экземпляры объектов коллекций могут быть разными (ArrayList, LinkedList и т.д.):

В остальном для коллекций сохраняются все свойства десериализации массивов.

Десериализация в пользовательские типы

В качестве дополнительной функции библиотека может работать с пользовательскими классами. Пользовательский тип обязательно должен иметь конструктор: MyClass(String), в противном случае будет вызвано исключение. Уровень видимости конструктора не имеет значения, он может быть как public, так и private:

Читайте также:  Animal crossing русификатор андроид

Как видите, библиотеке все равно, что нужный конструктор обозначен модификатором private. В результате в поле value класса T будет записано значение из файла конфигурации.

Модификаторы уровней доступа

Стоит отметить, что библиотеке nProperty абсолютно все равно, какие модификаторы доступа имеет поле, метод или конструктор — библиотека работает через механизм Reflections и управляет этими модификаторами самостоятельно. Конечно же, вмешательство в модификаторы никак не коснется других частей приложения, к которым библиотека отношения не имеет.

Инициализация всех членов класса

В предыдущих примерах видно, что при большом количестве полей в конфигурации придется написать большое кол-во аннотаций @Сfg. Чтобы избежать этой рутинной работы nProperty позволяет добавить аннотацию к самому классу, тем самым обозначив все поля класса как потенциальные поля для записи в них настроек из файла конфигурации:

Здесь стоит обратить внимание на член класса log. Ему назначена аннотация @Сfg с включенным свойством ignore. Это свойство означает, что данное поле не будет использоваться библиотекой при чтении конфигурации, а попросту будет пропущено. Данное свойство следует использовать только в случае, когда аннотация действует на весь класс, как показано в примере выше.

Значения по умолчанию

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

В данном случае после парсинга конфигурации в поле WRONG_PROPERTY будет храниться все то же значение 9000.

Переопределение имен

В случаях, когда имя поля класса не совпадает с именем конфигурации в конфигурационном файле, его можно принудительно переопределить:

Естественно, если есть возможность сохранять равнозначность имен в коде и в файлах конфигурации, то лучше так и делать — это избавит от необходимости аннотировать каждое поле класса.

Работа с не статичными полями классов

Библиотека способна работать как с классами, так и с их экземплярами. Это определяется путем различных вызовов метода ConfigParser.parse():

Как видно, в примере использованы два разных вызова одного и того же метода. После отработки метода ConfigParser.parse(Example11.class, «config/example.ini») в SOME_INT_VALUE будет нуль, причем это совершенно не зависит от файла конфигурации, потому что данное поле не является статичным и не может быть использовано без экземпляра объекта.

Сразу после второго вызова ConfigParser.parse(new Example11(), «config/example.ini») поле SOME_INT_VALUE для созданного объекта примет значение в соответствии с содержанием файла конфигурации.

Следует аккуратно пользоваться этой возможностью библиотеки, так как могут появиться ситуации, когда конфигурация не будет прогружаться по «непонятной» причине, а на самом деле окажется, что просто не был проставлен модификатор static.

Использование методов

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

Существует три решения в таких ситуациях:

  1. самостоятельно проверить или изменить значение после того, как библиотека проанализирует файл настроек и заполнит все поля класса
  2. создать в качестве типа свой класс-обертку с конструктором (как было показано выше)
  3. исключить поле класса из списка свойств и назначить его методу

Самый удобный и корректный способ — №3. Библиотека nProperty позволяет работать не только с полями, но и с методами:

Здесь в метод checkIntArray(String) в качестве первого параметра будет передано значение SOME_INT_ARRAY из файла конфигурации. Это очень удобный механизм для случаев, когда стандартные решения библиотеки не подходят. В методе-обработчике можно делать все, что угодно.

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

Читайте также:  Kis для android key

Как и прежде поддерживается преобразование типов, если тип первого параметра метода отличен от String.

Как и с полями класса, если имя метода эквивалентно имени настройки в файле конфигурации, то можно опустить задание имени в аннотации.

Обработка событий

Библиотека nProperty позволяет обрабатывать некоторые события во время чтения конфигурации. Для того, чтобы реализовать обработку событий, необходимо реализовать интерфейс IPropertyListener и все его методы. Вызов событий возможен только в случае работы с полноценными объектами, экземплярами класса, реализующего интерфейс IPropertyListener.

Поддерживаемые события:

  • onStart(String path) — отправляется перед началом загрузки файла конфигурации
  • onPropertyMiss(String name) — вызывается в случае, если некоторая именованная конфигурация не была найдена в файле настроек, но была обозначена в классе аннотацией @Сfg
  • onDone(String path) — вызывается при завершении загрузки файла конфигурации
  • onInvalidPropertyCast(String name, String value) — вызывается в случае, когда удалось прочитать значение настройки из файла конфигурации, но не удалось привести это значение к типу соответствующего поля класса

В приведенном примере будут вызваны все 4 события. Событие onPropertyMiss будет вызвано из-за поля SOME_MISSED_VALUE, которое отсутствует в файле конфигурации. Событие onInvalidPropertyCast будет вызвано из-за неверного типа поля SOME_INT_ARRAY.

Использование потоков и дескрипторов файлов

Библиотека умеет принимать на вход не только имена файлов, также возможна передача объекта java.io.File, или потока данных, производного от абстрактного класса java.io.InputStream:

Как видно, в приведенном примере в случае работы с потоком, библиотека требует дополнительно указать название конфигурации, так как невозможно его получить из низкоуровневого объекта FileInputStream. Название не является важной частью и будет использовано библиотекой для отображения информации (в том числе, при работе с событиями).

Таким образом, данные могут быть получены не только из файловой системы, но и от любого источника данных, работающего по стандартам Java. Умение работать с java.io.InputStream дает возможность библиотеке быть успешно примененной в операционных системах Android:

Замечания

В связи с не очень прозрачной работой SecurityManager’a библиотека имеет ограничение на тип задаваемого поля конфигуратора: поле не должно иметь модификатора final.

Лицензия

Библиотека распространяется по лицензии Apache License v.2.0

Источник

Простой пример работы с Property файлами в Java

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

Шаг 0. Создание проекта

Начнем с того что создадим простой Maven проект, указав название и имя пакета:

Структура, которая получится в конце проекта довольно таки простая.

Как видите у нас только два файла, первый – Main.java, а второй – config.properties.

Шаг 2. Добавляем конфигурационные данные в проперти файл

Проперти файлы либо файлы свойств – предназначены, для того чтобы хранить в них какие-то статические данные необходимые проект, например логин и пароль к БД.

Давайте добавим в наш config.properties логин и пароль (это любые данные, для того чтобы продемонстрировать работу с property файлами).

Содержимое config.properties:

<ключ> – это уникальное имя, по которому можно получить доступ к значению, хранимому под этим ключом.

<значение> – это текст, либо число, которое вам необходимо для выполнения определённой логики в вашей программе.

Шаг 3. Получаем Property данные

Как можно видеть в структуре проекта выше, там есть класс Main.java давайте его создадим и напишем в нем следующее:

Обращаясь к property.getProperty(<ключ>) – вы получаете его значение.

Вот такой краткий, но думаю познавательный урок.

Источник

Java Properties file examples

By mkyong | Last updated: April 11, 2019

Viewed: 2,749,156 (+8,337 pv/w)

Normally, Java properties file is used to store project configuration data or settings. In this tutorial, we will show you how to read and write to/from a .properties file.

A simple Maven project structure for testing.

Читайте также:  Metal gear rising revengeance для андроида

1. Write to the properties file

Set the property key and value, and save it somewhere.

The path/to/config.properties is created.

2. Load a properties file

Load a properties file from the file system and retrieved the property value.

3. Load a properties file from classpath

Load a properties file config.properties from project classpath, and retrieved the property value.

4. Prints everything from a properties file

Load a properties file config.properties from project classpath, and print out the keys and values.

Download Source Code

References

mkyong

Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

I’m always getting “Sorry, unable to find ” + filename in scenario 4

Note: I have a properties file which works just fine with scenario no. 2

Can you please help?

For App4, it loads fro src/main/resources/config.properties

can anyone help me how to retrieve pdfs from path stored in database

I can’t find config.properties file. Can anyone help me ?

Ohhh man that you can create by your ownan that’s easy part

Article is updated, for App1 and App2, you need to defined your own location, by default it will saved into the project root folder.

For App3, it loads from src/main/resources/config.properties

You need to add to the project manually. .

you can either give the exact directory or go one level higher i.e. src/main/resources/config.properties

it is possible to use variables into a properties file? something like this:

Article is updated, App3 is the class name.

App3 is mistake there. It should be App.
That means the name of class thats all.

I see how to read from the classpath but what about writing to it?

Refer to App1 and App2 examples.

sir i need simplry programme of properties file pls reply my emaid:gthiru59@yahoo.com

Can you share the ide theme name plz

How to read and write .cfg file in java?

I included this as a jar in my main application. Not getting any errors but I am unable to see .properties file being created on liberty server and subsequently properties not getting loaded in other java files.

Thansk , I found this very useful

Hello, i’m new to java, can u tell me what’s the different between point 2 (Load a properties file from the file system) and point 3 (Load a properties file config.properties from project classpath), and can you suggest me when i should use point 2 or point 3 ? Thank you very much.

i want to read from config.properties and store it into new environment.properties. anyone help

Is that possible to add the property name on the run time, which the existing property file dosent have such value.

Yes, see App1 example.

@Mkyong you are a living legend.

how to add html tags and affect in front-end through resource bundle file, Ex: i need to show bolder text front-end, i tried BOLDER but it doesn’t work.

My file is not getting picked up for reading. Please give me some suggestion

static public void main(String args[]) throws IOException <

Properties prop = new Properties();

InputStream input = new FileInputStream(“F:\workspace\Practice\config.properties”);

Set set = prop.keySet();

for (Object r : set) <
System.out.println(r + ” value is: ” + prop.getProperty((String) r));

a simple way to have key value pair printed

i followed the tutorial, using this code:
1. Write to properties file
tested the code on a tomcat but not create the file why? how to know why?
2) in wich path was created the file?
my tomcat is installed on /opt/tomcat

not i tested sam ecode on a glassfish server and worked, created the file on:
/opt/glassfish4/glassfish/domains/swManzana/config/

Источник

Оцените статью