Java 8のラムダ式とStreamを使ってINIファイルをパースする
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のサンプルコードとしてこのくらいの複雑度のものがあれば、そこから発展させやすいよね。と思ったので、載せておきました。いじょ。
コメントを記入