Kotlin: 標準入力を読んで行ごとに処理

<関連記事の案内です>

<案内おわり>

簡易版

お手軽に済ませたいならこれでよいっぽい。

readLine - Kotlin Programming Language

// Cat1.kts

while (true) {
    val line : String? = readLine()
    if (line == null) {
        break
    }
    println(line)
}
$ cat Cat1.kts | kotlin Cat1.kts | cat -A
while (true) {$
    val line : String? = readLine()$
    if (line == null) {$
        break$
    }$
    println(line)$
}$

改行を変化させない+エンコーディング指定版

上記の簡易版では改行の情報が失われて困るので、そうならないようにしたもの。

  • 改行が LF または CRLF であることを前提にしています。
  • パフォーマンスについては調べていません。 もっと効率のよい書き方はあると思います。BufferedReader 使うとか。
// Cat2.kts

import java.nio.charset.StandardCharsets
import java.io.InputStreamReader
import java.io.OutputStreamWriter

InputStreamReader(System.`in`, StandardCharsets.UTF_8).use { isr ->
    OutputStreamWriter(System.out, StandardCharsets.UTF_8).use { osw ->
        val sb = StringBuilder()
        while (true) {
            val n = isr.read()
            if (n == -1) {
                break
            }
            val c = n.toChar()
            sb.append(c)
            if (c == '\n') {
                val line = sb.toString()
                osw.write(line)
                sb.clear()
            }
        }
        val line = sb.toString()
        osw.write(line)
    }
}

なファイルで確認(区切り線っぽく見える ----... はプロンプトの一部):

--------------------------------
$ cat end_with_newline.txt 
あ
aa
bb
--------------------------------
$ cat -A end_with_newline.txt 
M-cM-^AM-^B^M$
aa^M$
bb^M$
--------------------------------
$ cat end_with_newline.txt | kotlin Cat2.kts | cat -A
M-cM-^AM-^B^M$
aa^M$
bb^M$
--------------------------------
$

なファイルで確認:

--------------------------------
$ cat end_without_newline.txt 
あ
aa
bb--------------------------------
$ cat -A end_without_newline.txt 
M-cM-^AM-^B^M$
aa^M$
bb--------------------------------
$ cat end_without_newline.txt | kotlin Cat2.kts | cat -A
M-cM-^AM-^B^M$
aa^M$
bb--------------------------------
$

バージョン

$ kotlin -version
Kotlin version 1.3.72-release-468 (JRE 1.8.0_252-8u252-b09-1~18.04-b09)