Home About
Kotlin , JSON

kotlin script が便利 Javaのライブラリも使える

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

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

kotlin ./json.main.kts

または単に:

./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 のようにする必要があるようです。

json.main.kts :

#!/usr/bin/env kotlin

@file:Repository("https://mvnrepository.com")
@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 の方で面倒を見てくれます。

このファイルを指して実行するには当然実行権が必要なのでそれを付けます。

$ chmod u+x ./json.main.kts

そして、実行:

$ ./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 :

#!/usr/bin/env kotlin

@file:Repository("https://mvnrepository.com")
@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 のライブラリ資産が使えるメリットが、起動のオーバーヘッドのマイナスを上回るケースで使うべきツールである。