たかぎとねこの忘備録

プログラミングに関する忘備録を自分用に残しときます。マサカリ怖い。

Kotlinでプロジェクト内のディレクトリにある複数のJSONファイルをまとめて処理してみる

次の様なディレクトリの構成を考えてみる。

  • a_lot_of_settings
    • a
    • b
    • c
    • main
      • kotlin
        • com
          • takagimeow
            • main.kt

a_lot_of_settingsディレクトリの中にはaディレクトリとbディレクトcディレクトリが存在し、それぞれのディレクトリの中にsettings.json`が存在する。

このsettings.jsonをそれぞれ読み取り処理をしたい。

settings.jsonの中身は次のようなフォーマットになっている。

{
  "name": "takagimeow"
}

このフォーマットと一致するdata classを実装する。

data class Settings(
    val name: String,
)

JSONのパースライブラリとして、Jacksonを使用する。

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule

...

val mapper = jacksonObjectMapper()
mapper.registerKotlinModule()

File()のコンストラクタに渡す相対パスは、実行しようとしているmain()関数が記述されたファイルの場所が起点ではなく、プロジェクトのルートディレクトリが起点となるので注意が必要。

File("./a_lot_of_settings").walk().forEach { dir ->
    if (dir.isDirectory && dir.toString() != "./a_lot_of_settings") {
        val jsonString: String = File("$dir/settings.json").readText(Charsets.UTF_8)
        val result: Settings = mapper.readValue(jsonString, Settings::class.java)
        println("name: ${result.name}")
    }
}

dirには./a_lot_of_settings自身も格納されてしまうので弾いている。

最終的な実装は次の様な感じ。

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import java.io.File

data class Settings(
    val name: String,
)

suspend fun main() {
    val mapper = jacksonObjectMapper()
    mapper.registerKotlinModule()
    File("./a_lot_of_settings").walk().forEach { dir ->
        if (dir.isDirectory && dir.toString() != "./a_lot_of_settings") {
            val jsonString: String = File("$dir/settings.json").readText(Charsets.UTF_8)
            val result: Settings = mapper.readValue(jsonString, Settings::class.java)
            println("name: ${result.name}")
        }
    }
}

参考

Read a Json file with Kotlin

Kotlin - ディレクトリのすべてのファイルのリスト出力