last update 2017年8月15日 16:45

Java 8のラムダ式とStreamを使ってINIファイルをパースする

Java code

Java 8 で追加されたラムダ式と Stream を使い、Windows のINIファイルをパースするコードを書いたので共有しておきます。

  • INIファイルのセクションは無視する仕様
  • お尻のホワイトスペースはカットする仕様

ですので、ちゃんとしたい人は Apache Commons Configuration とかを使ってください。

プログラム構造的には、CSV をパースするときの参考にもなると思います。

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.stream.Stream;

public class IniFileToProperties {

    public static Properties load(String filePath, Charset charset) throws IOException {
        Properties properties = new Properties();
        try (Stream stream = Files.lines(Paths.get(filePath), charset)) {  // close処理は不要
            stream.forEach(line -> {
                // 行前後の空白を削除
                String trimmedLine = line.trim();
                // 空行は無視
                if (trimmedLine.isEmpty()) { return; }
                // コメント行は無視
                if (trimmedLine.substring(0,1).equals(";")) { return; }
                // セクション行も無視
                if (trimmedLine.substring(0,1).equals("[")) { return; }
                // 行の現れる最初の"="でパース
                int p = trimmedLine.indexOf("=");
                // "=" が無い場合は無視
                if (p == -1) { return; }
                // properties構築
                properties.setProperty(trimmedLine.substring( 0, p ), trimmedLine.substring( p + 1 ));
            });
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
        return properties;
    }
}

呼び出し側は↓こんな感じ。

Properties settings = IniFileToProperties.load("C:\\where\to\ini_file.ini", Charset.forName("SJIS"));
String baseDir = settings.getProperty("base_dir");

なんだか Java っぽくない Scala 的な書き方で、スッキリしてますね。

ポイントを挙げるなら、多分、以下の2点。

  • for 構文でいう continue に近い動きをするには、Stream.forEach に与えるラムダ式で return すればよい。(break相当の機能は無い)
  • ローカル変数のスコープ内にあるラムダ式の無名クラスからは、そのローカル変数へアクセスできる。(この場合、無名 Consumer クラスから直接 properties へアクセスし、結果を出力している。)

前者はただのTIPSですが、後者はJava的な考え方が染み付いていて、かつ、ラムダ式の中身が無名クラスだと分かっているほど、気が付くのに時間が掛かりそうだと感じました。

今どきINIファイルなんか読まねーよ。という人は多いと思いますが、ラムダ式とStreamのサンプルコードとしてこのくらいの複雑度のものがあれば、そこから発展させやすいよね。と思ったので、載せておきました。いじょ。

コメントを記入

CAPTCHA