java 57 lines · 10 steps

Parsing INI files in Java

A line-oriented parser that reads an INI file into nested maps of sections and key-value pairs.

Explained by highlit
1public final class IniParser {
2 
3 private static final Pattern SECTION = Pattern.compile("\\[(.+?)\\]");
4 
5 public Map<String, Map<String, String>> parse(Path file) throws IOException {
6 Map<String, Map<String, String>> sections = new LinkedHashMap<>();
7 Map<String, String> current = sections.computeIfAbsent("", k -> new LinkedHashMap<>());
8 
9 try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
10 String raw;
11 int lineNo = 0;
12 while ((raw = reader.readLine()) != null) {
13 lineNo++;
14 String line = stripComment(raw).trim();
15 if (line.isEmpty()) {
16 continue;
17 }
18 
19 Matcher section = SECTION.matcher(line);
20 if (section.matches()) {
21 String name = section.group(1).trim();
22 current = sections.computeIfAbsent(name, k -> new LinkedHashMap<>());
23 continue;
24 }
25 
26 int eq = line.indexOf('=');
27 if (eq < 0) {
28 throw new IllegalArgumentException("Malformed entry at line " + lineNo + ": " + raw);
29 }
30 
31 String key = line.substring(0, eq).trim();
32 String value = unquote(line.substring(eq + 1).trim());
33 current.put(key, value);
34 }
35 }
36 
37 sections.get("").entrySet().removeIf(e -> false);
38 if (sections.get("").isEmpty()) {
39 sections.remove("");
40 }
41 return sections;
42 }
43 
44 private static String stripComment(String line) {
45 int hash = line.indexOf('#');
46 int semi = line.indexOf(';');
47 int cut = Math.min(hash < 0 ? line.length() : hash, semi < 0 ? line.length() : semi);
48 return line.substring(0, cut);
49 }
50 
51 private static String unquote(String value) {
52 if (value.length() >= 2 && value.startsWith("\"") && value.endsWith("\"")) {
53 return value.substring(1, value.length() - 1);
54 }
55 return value;
56 }
57}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Tracking a mutable current-section reference turns a flat line loop into a stateful parser.
  2. 2LinkedHashMap preserves insertion order, so sections and keys come back as they appeared in the file.
  3. 3Stripping comments and unquoting before parsing keeps the core logic focused on structure, not cleanup.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Parsing INI files in Java — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code