Я использую этот код:
var reader: Int = 0
val buffer = CharArray(4096)
var output = StringBuilder()
val process = processBuilder.start()
var inputStream = BufferedReader(InputStreamReader(process.getInputStream()));
while ({ reader = inputStream.read(buffer); reader }() > 0) {
output.append(buffer, 0, reader)
println("Debug: " + output.toString())
}
inputStream.close()
process.waitFor()
Он отлично работает, но у меня есть 2 проблемы, из-за которых он не соответствует моим потребностям:
1) Он не извлекает каждую строку в режиме реального времени. Он буферизует некоторые строки из фактического вывода и показывает их в каждом цикле.
2) Результат прилагается. Мне нужна только фактическая и единственная строка вывода на каждой итерации.
Довольно элегантное решение в стиле Kotlin:
var output: String = ""
val process = processBuilder.start()
val inputStream = BufferedReader(InputStreamReader(process.getInputStream()))
while ( inputStream.readLine()?.also { output = it } != null) {
println("Debug: " + output)
}
inputStream.close()
process.waitFor()
Оператор while эквивалентен оператору Java:
while ( (output = inputStream.readLine()) != null) {
println("Debug: " + output)
}
В Kotlin вы не можете назначать переменные внутри операторов, но с помощью цепочки также вы можете включить дополнительный код, который будет выполняться одновременно. Оператор Элвиса (?) после readLine позволяет "it" стать нулевым, чтобы выполнить последнюю проверку. Это необходимо, чтобы избежать сбоев.