The best way to parse such a file (without using dedicated 3rd party libraries), is via the regex API, and its front-end class Scanner
. Unfortunately, the best operations to implement it via Stream API, are currently missing. Namely, Matcher.results()
and Scanner.findAll(…)
are not there yet. So unless we want to wait until Java?9, we have to create similar methods for a Java?8 compatible solution:
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);
}
Using methods with a similar semantic allows us to replace their usage with the standard API methods, once Java?9 is released and becomes commonplace.
Using these two operations, you can parse your file using
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)))));
}
the resulting map m
holds all information, mapping from the group names to another map holding the key/value pairs, i.e. you can print an equivalent .ini
file using:
m.forEach((group,attr)-> {
System.out.println("["+group+"]");
attr.forEach((key,value)->System.out.println(key+"="+value));
});
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…