Java Language
Класс свойств
Поиск…
Вступление
Объект properties содержит пару ключей и значений как строку. Класс java.util.Properties является подклассом Hashtable.
Его можно использовать для получения значения свойства на основе ключа свойства. Класс Properties предоставляет методы для получения данных из файла свойств и хранения данных в файле свойств. Более того, его можно использовать для получения свойств системы.
Преимущество файла свойств
Перекомпиляция не требуется, если информация изменяется из файла свойств: если какая-либо информация изменена с
Синтаксис
- В файле свойств:
- ключ = значение
- #комментарий
замечания
Объект Properties - это карта , ключи и значения которой являются строками по соглашению. Хотя методы карты могут быть использованы для доступа к данным, тем больше типизированные методы GetProperty , SetProperty и stringPropertyNames обычно используются вместо этого.
Свойства часто хранятся в файлах свойств Java, которые представляют собой простые текстовые файлы. Их формат подробно описан в методе Properties.load . В итоге:
- Каждая пара ключ / значение представляет собой строку текста с пробелами, равно (
=
) или двоеточие (:
) между ключом и значением. Уравнение или двоеточие может иметь любое количество пробелов до и после него, которое игнорируется. - Ведущие пробелы всегда игнорируются, всегда включается конечный пробел.
- Обратная косая черта может использоваться для удаления любого символа (кроме нижнего регистра
u
). - Обратная косая черта в конце строки указывает, что следующая строка является продолжением текущей строки. Однако, как и во всех строках, ведущие пробелы в строке продолжения игнорируются.
- Как и в исходном коде Java,
\u
за которым следуют четыре шестнадцатеричных цифры, представляет символ UTF-16.
Большинство фреймворков, включая собственные средства Java SE, такие как java.util.ResourceBundle, загружают файлы свойств как InputStreams. При загрузке файла свойств из InputStream этот файл может содержать только символы ISO 8859-1 (то есть символы в диапазоне 0-255). Любые другие символы должны быть представлены как \u
экранирование. Тем не менее, вы можете написать текстовый файл в любой кодировке и использовать инструмент native2ascii (который поставляется с каждым JDK), чтобы сделать это для вас.
Если вы загружаете файл свойств собственным кодом, он может быть в любой кодировке, если вы создаете Reader (например, InputStreamReader ) на основе соответствующей кодировки . Затем вы можете загрузить файл с использованием load (Reader) вместо метода устаревшей загрузки (InputStream).
Вы также можете хранить свойства в простом XML-файле, который позволяет самому файлу определять кодировку. Такой файл может быть загружен с помощью метода loadFromXML . DTD, описывающий структуру таких файлов XML, находится по адресу http://java.sun.com/dtd/properties.dtd .
Загрузка свойств
Чтобы загрузить файл свойств в комплекте с вашим приложением:
public class Defaults {
public static Properties loadDefaults() {
try (InputStream bundledResource =
Defaults.class.getResourceAsStream("defaults.properties")) {
Properties defaults = new Properties();
defaults.load(bundledResource);
return defaults;
} catch (IOException e) {
// Since the resource is bundled with the application,
// we should never get here.
throw new UncheckedIOException(
"defaults.properties not properly packaged"
+ " with application", e);
}
}
}
Предоставление файла свойств: завершение пробела
Внимательно посмотрите на эти два файла свойств, которые кажутся полностью идентичными:
за исключением того, что они действительно не идентичны:
(скриншоты из Notepad ++)
Так как конечный пробел сохраняется, значение lastName
будет "Smith"
в первом случае, а "Smith "
во втором случае.
Очень редко это то, что пользователи ожидают, и одно, и может только предположить, почему это поведение класса Properties
по умолчанию. Однако легко создать расширенную версию Properties
которая устраняет эту проблему. Следующий класс, TrimmedProperties , делает именно это. Это замена для стандартного класса Properties.
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Map.Entry;
import java.util.Properties;
/**
* Properties class where values are trimmed for trailing whitespace if the
* properties are loaded from a file.
*
* <p>
* In the standard {@link java.util.Properties Properties} class trailing
* whitespace is always preserved. When loading properties from a file such
* trailing whitespace is almost always <i>unintentional</i>. This class fixes
* this problem. The trimming of trailing whitespace only takes place if the
* source of input is a file and only where the input is line oriented (meaning
* that for example loading from XML file is <i>not</i> changed by this class).
* For this reason this class is almost in all cases a safe drop-in replacement
* for the standard <tt>Properties</tt>
* class.
*
* <p>
* Whitespace is defined here as any of space (U+0020) or tab (U+0009).
* *
*/
public class TrimmedProperties extends Properties {
/**
* Reads a property list (key and element pairs) from the input byte stream.
*
* <p>Behaves exactly as {@link java.util.Properties#load(java.io.InputStream) }
* with the exception that trailing whitespace is trimmed from property values
* if <tt>inStream</tt> is an instance of <tt>FileInputStream</tt>.
*
* @see java.util.Properties#load(java.io.InputStream)
* @param inStream the input stream.
* @throws IOException if an error occurred when reading from the input stream.
*/
@Override
public void load(InputStream inStream) throws IOException {
if (inStream instanceof FileInputStream) {
// First read into temporary props using the standard way
Properties tempProps = new Properties();
tempProps.load(inStream);
// Now trim and put into target
trimAndLoad(tempProps);
} else {
super.load(inStream);
}
}
/**
* Reads a property list (key and element pairs) from the input character stream in a simple line-oriented format.
*
* <p>Behaves exactly as {@link java.util.Properties#load(java.io.Reader)}
* with the exception that trailing whitespace is trimmed on property values
* if <tt>reader</tt> is an instance of <tt>FileReader</tt>.
*
* @see java.util.Properties#load(java.io.Reader) }
* @param reader the input character stream.
* @throws IOException if an error occurred when reading from the input stream.
*/
@Override
public void load(Reader reader) throws IOException {
if (reader instanceof FileReader) {
// First read into temporary props using the standard way
Properties tempProps = new Properties();
tempProps.load(reader);
// Now trim and put into target
trimAndLoad(tempProps);
} else {
super.load(reader);
}
}
private void trimAndLoad(Properties p) {
for (Entry<Object, Object> entry : p.entrySet()) {
if (entry.getValue() instanceof String) {
put(entry.getKey(), trimTrailing((String) entry.getValue()));
} else {
put(entry.getKey(), entry.getValue());
}
}
}
/**
* Trims trailing space or tabs from a string.
*
* @param str
* @return
*/
public static String trimTrailing(String str) {
if (str != null) {
// read str from tail until char is no longer whitespace
for (int i = str.length() - 1; i >= 0; i--) {
if ((str.charAt(i) != ' ') && (str.charAt(i) != '\t')) {
return str.substring(0, i + 1);
}
}
}
return str;
}
}
Сохранение свойств как XML
Сохранение свойств в файле XML
Способ хранения файлов свойств в виде файлов XML очень похож на способ хранения их как файлов .properties
. Просто вместо использования store()
вы будете использовать storeToXML()
.
public void saveProperties(String location) throws IOException{
// make new instance of properties
Properties prop = new Properties();
// set the property values
prop.setProperty("name", "Steve");
prop.setProperty("color", "green");
prop.setProperty("age", "23");
// check to see if the file already exists
File file = new File(location);
if (!file.exists()){
file.createNewFile();
}
// save the properties
prop.storeToXML(new FileOutputStream(file), "testing properties with xml");
}
Когда вы откроете файл, он будет выглядеть следующим образом.
Загрузка свойств из файла XML
Теперь для загрузки этого файла в качестве properties
вам нужно вызвать loadFromXML()
вместо load()
который вы будете использовать с обычными файлами .propeties
.
public static void loadProperties(String location) throws FileNotFoundException, IOException{
// make new properties instance to load the file into
Properties prop = new Properties();
// check to make sure the file exists
File file = new File(location);
if (file.exists()){
// load the file
prop.loadFromXML(new FileInputStream(file));
// print out all the properties
for (String name : prop.stringPropertyNames()){
System.out.println(name + "=" + prop.getProperty(name));
}
} else {
System.err.println("Error: No file found at: " + location);
}
}
Когда вы запустите этот код, вы получите следующее в консоли:
age=23
color=green
name=Steve