Home About Contact
Kotlin , Kotlin Script , JSON

Kotlin Script が便利 Javaのライブラリも使える

Kotlin が気軽に使える Kotlin Script 便利です。 インストール方法や使い方の詳細はこちら Kotlin Scripting Examples: kotlin-main-kts usages をご覧ください。

kotlin 関連のインストールがされている前提ですが、以下のように kotlin script を実行できます。

kotlinc -script ./json.main.kts

以下にいくつか具体例を示します。

その1) org.json を使うスクリプトの例

以前のエントリー org.json.JSONObject で JSON データを読むときに欠落しているパラメータを上手に扱いたいのコードをスクリプトとして実行してみます。

元のコード main.kts :

import org.json.*

val jsonData = """{
    "penList" : [
        {"name": "red-bold", "color": "240,0,0", "width": 6},
        {"name": "black-normal", "color": "0,0,0"},
        {"name": "light", "width": 3},
        {"color": "102,102,102"}
    ]
}"""

val rootObj = JSONObject(jsonData)
val penListArray =  rootObj.getJSONArray("penList")

0.until( penListArray.length() ).forEach { index->
    val penObject = penListArray[index] as JSONObject
    println( "- ${penObject}" )
}

これを json.main.kts にファイル名変更します。 スクリプトとして実行するにはファイル名を hoge.main.kts のようにする必要があるようです。 main.kts のままではうまく作動しない。

json.main.kts :

@file:Repository("https://repo1.maven.org/maven2/")
@file:DependsOn("org.json:json:20210307")

import org.json.*

val jsonData = """{
    "penList" : [
        {"name": "red-bold", "color": "240,0,0", "width": 6},
        {"name": "black-normal", "color": "0,0,0"},
        {"name": "light", "width": 3},
        {"color": "102,102,102"}
    ]
}"""

val rootObj = JSONObject(jsonData)
val penListArray =  rootObj.getJSONArray("penList")

0.until( penListArray.length() ).forEach { index->
    val penObject = penListArray[index] as JSONObject
    println( "- ${penObject}" )
}

元の main.kts とほぼ同じですが @file の行が追加されています。 この記述により、org.json のライブラリを自分でダウンロードしなくても、kotlin の方で面倒を見てくれます。

そして、実行:

$ kotlinc -script ./json.main.kts
- {"color":"240,0,0","name":"red-bold","width":6}
- {"color":"0,0,0","name":"black-normal"}
- {"name":"light","width":3}
- {"color":"102,102,102"}

うまくいきました。

その2) opencsv を使う例

もう一つ例を見てみましょう。 opencsv を使って CSV を読み書きする例です。

こんなCSVデータ price.csv :

id,name,price
001,macbook air,98000
002,macbook pro,158000
003,mac mini,78000
004,iMac,154800

これを読み込み、価格を倍にして price-result.csv に保存する csv.main.kts :

@file:Repository("https://repo1.maven.org/maven2/")
@file:DependsOn("com.opencsv:opencsv:5.5")

import java.io.*
import com.opencsv.CSVReader
import com.opencsv.CSVWriter

val inputCsvFile = File("price.csv")
val outputCsvFile = File("price-result.csv")

val csvReader = CSVReader(InputStreamReader(FileInputStream(inputCsvFile), "UTF-8"))
val rows: List<Array<String>> = csvReader.readAll()
csvReader.close()

rows.forEach { row->
    println( row.joinToString("|") )
}

val csvWriter = CSVWriter(OutputStreamWriter(FileOutputStream(outputCsvFile),"UTF-8"))
csvWriter.writeNext( rows[0] )
IntRange(1, rows.size-1).forEach { index->
    val row = rows[index]
    csvWriter.writeNext( arrayOf<String>(row[0], row[1], (row[2].toInt() * 2).toString() ) )
}

csvWriter.close()

実行します。

$ ./csv.main.kts
id|name|price
001|macbook air|98000
002|macbook pro|158000
003|mac mini|78000
004|iMac|154800

書き出した price-result.csv ファイルの中身をチェック:

$ cat ./price-result.csv
"id","name","price"
"001","macbook air","196000"
"002","macbook pro","316000"
"003","mac mini","156000"
"004","iMac","309600"

価格が倍になっています。

まとめ

kotlin script 便利。Groovy の @Grab 相当の機能があり、スクリプトとして手軽に使える。 Golang や Node.js と比べると kotlin script は JavaVM 上で動くで起動時のオーバーヘッドがあり作動が遅い。 試していないが、この辺は kotlin native などを使えば解消されるのだろうか? いや、それより Java のライブラリ資産が使えるメリットが、起動のオーバーヘッドのマイナスを上回るケースで使うべきツールである。