Еще один ответ (в январе 2018 г.) на старый вопрос (в январе 2009 г.).
Спецификация файла свойств Java описана в JavaDoc <a href="https://docs.oracle.com/javase/9/docs/api/java/util/Properties.html#load-java.io.Reader-" rel="noreferrer">java.util.Properties.load(java.io.Reader)</a>
. Одна проблема заключается в том, что спецификация немного сложнее, чем первое впечатление, которое мы можем иметь. Другая проблема заключается в том, что в некоторые ответы здесь произвольно добавляются дополнительные спецификации - например, ;
и '
рассматриваются как начало строк комментариев, но не должны. Двойные / одинарные кавычки вокруг значений свойств удаляются, но они не должны быть.
Следующие пункты необходимо учитывать.
- Существует два вида линий: натуральные линии и логические линии .
- Естественная линия заканчивается
\n
, \r
, \r\n
или концом потока.
- Логическая строка может быть разбросана по нескольким смежным естественным строкам, если экранировать последовательность символов конца строки с обратной косой чертой
\
.
- Любые пробелы в начале второй и последующих натуральных строк в логической строке отбрасываются.
- Пробелы - это пробел (
, \u0020
), табуляция (\t
, \u0009
) и подача формы (\f
, \u000C
).
- Как явно указано в спецификации, "недостаточно просто исследовать символ, предшествующий последовательности конца строки, чтобы решить, экранирован ли конец строки; должно быть нечетное количество непрерывных обратных косых черт для конца строки чтобы быть экранированным. Поскольку ввод обрабатывается слева направо, ненулевое четное число 2n непрерывных обратных косых черт перед разделителем строки (или в другом месте) кодирует n обратных косых черт после обработки escape. "
=
используется в качестве разделителя между ключом и значением.
:
также используется в качестве разделителя между ключом и значением.
- Разделитель между ключом и значением может быть опущен.
- Строка комментария имеет
#
или !
в качестве своих первых непробельных символов, что означает, что допускаются первые пробелы перед #
или !
.
- Строка комментария не может быть расширена до следующих натуральных строк, даже если ее символу конца строки предшествует
\
.
- Как прямо указано в спецификации,
=
, :
и пробелы могут быть встроены в ключ, если они выходят из-за обратной косой черты.
- Даже символы конца строки могут быть включены с помощью escape-последовательностей
\r
и \n
.
- Если значение опущено, в качестве значения используется пустая строка.
\uxxxx
используется для представления символа Unicode.
- Символ обратной косой черты перед недопустимым escape-символом не рассматривается как ошибка; он тихо сбрасывается.
Так, например, если test.properties
имеет следующее содержимое:
# A comment line that starts with '#'.
# This is a comment line having leading white spaces.
! A comment line that starts with '!'.
key1=value1
key2 : value2
key3 value3
key\
4=value\
4
\u006B\u0065\u00795=\u0076\u0061\u006c\u0075\u00655
\k\e\y\6=\v\a\lu\e\6
\:\ \= = \\colon\\space\\equal
его следует интерпретировать как следующие пары ключ-значение.
+------+--------------------+
| KEY | VALUE |
+------+--------------------+
| key1 | value1 |
| key2 | value2 |
| key3 | value3 |
| key4 | value4 |
| key5 | value5 |
| key6 | value6 |
| : = | \colon\space\equal |
+------+--------------------+
PropertiesLoader
класс в Authlete.Authlete Пакет NuGet может интерпретировать формат спецификации. Пример кода ниже:
using System;
using System.IO;
using System.Collections.Generic;
using Authlete.Util;
namespace MyApp
{
class Program
{
public static void Main(string[] args)
{
string file = "test.properties";
IDictionary<string, string> properties;
using (TextReader reader = new StreamReader(file))
{
properties = PropertiesLoader.Load(reader);
}
foreach (var entry in properties)
{
Console.WriteLine($"{entry.Key} = {entry.Value}");
}
}
}
}
сгенерирует этот вывод:
key1 = value1
key2 = value2
key3 = value3
key4 = value4
key5 = value5
key6 = value6
: = = \colon\space\equal
Эквивалентный пример на Java выглядит следующим образом:
import java.util.*;
import java.io.*;
public class Program
{
public static void main(String[] args) throws IOException
{
String file = "test.properties";
Properties properties = new Properties();
try (Reader reader = new FileReader(file))
{
properties.load(reader);
}
for (Map.Entry<Object, Object> entry : properties.entrySet())
{
System.out.format("%s = %s\n", entry.getKey(), entry.getValue());
}
}
}
Исходный код, <a href="https://github.com/authlete/authlete-csharp/blob/master/Authlete/Util/PropertiesLoader.cs" rel="noreferrer">PropertiesLoader.cs</a>
, можно найти в authlete-csharp . xUnit тесты для PropertiesLoader
записаны в <a href="https://github.com/authlete/authlete-csharp/blob/master/Authlete.Tests/Util/PropertiesLoaderTest.cs" rel="noreferrer">PropertiesLoaderTest.cs</a>
.