Лучший способ разобрать такой файл (без использования специализированных библиотек 3 участника), осуществляется с помощью регулярных выражений API, и его передний конец класса Scanner
. К сожалению, лучшие операции по его реализации через Stream API в настоящее время отсутствуют. А именно, Matcher.results()
и Scanner.findAll(…)
еще нет. Так что, если мы не хотим, чтобы ждать, пока Java 9, мы должны создать аналогичные методы для решения в Java 8 совместимом:
public static Stream<MatchResult> findAll(Scanner s, Pattern pattern) {
return StreamSupport.stream(new Spliterators.AbstractSpliterator<MatchResult>(
1000, Spliterator.ORDERED|Spliterator.NONNULL) {
public boolean tryAdvance(Consumer<? super MatchResult> action) {
if(s.findWithinHorizon(pattern, 0)!=null) {
action.accept(s.match());
return true;
}
else return false;
}
}, false);
}
public static Stream<MatchResult> results(Matcher m) {
return StreamSupport.stream(new Spliterators.AbstractSpliterator<MatchResult>(
m.regionEnd()-m.regionStart(), Spliterator.ORDERED|Spliterator.NONNULL) {
public boolean tryAdvance(Consumer<? super MatchResult> action) {
if(m.find()) {
action.accept(m.toMatchResult());
return true;
}
else return false;
}
}, false);
}
Использование методов с подобной семантикой позволяет заменить их использование со стандартными методами API, когда Java 9 выпущен и становится обычным явлением.
Используя эти две операции, вы можете разобрать ваш файл, используя
Pattern groupPattern=Pattern.compile("\\[(.*?)\\]([^\\[]*)");
Pattern attrPattern=Pattern.compile("(.*?)=(.*)\\v");
Map<String, Map<String, String>> m;
try(Scanner s=new Scanner(Paths.get(context.io.iniFilename))) {
m = findAll(s, groupPattern).collect(Collectors.toMap(
gm -> gm.group(1),
gm -> results(attrPattern.matcher(gm.group(2)))
.collect(Collectors.toMap(am->am.group(1), am->am.group(2)))));
}
результирующее отображение m
содержит всю информацию, отображение имен групп на другой карте, удерживающих пар ключ/значение, то есть вы можете напечатать эквивалентный .ini
файл с помощью:
m.forEach((group,attr)-> {
System.out.println("["+group+"]");
attr.forEach((key,value)->System.out.println(key+"="+value));
});
Ваш вопрос непонятен - что вы пытаетесь включить? Похоже, вы, возможно, захотите * сначала написать метод, который читает строки и возвращает «Map» (где «ConfigurationBlock» - это ваш собственный тип, или, может быть, «Свойства»). –
Начните с отображения того, что вы хотите сделать с помощью обычного оператора switch без потока –
Вопрос изменен – elect