Ich habe kürzlich Code zum Lesen des gesamten Inhalts InputStream
eines Strings in Kotlin gesehen, wie zum Beispiel:
// input is of type InputStream
val baos = ByteArrayOutputStream()
input.use { it.copyTo(baos) }
val inputAsString = baos.toString()
Und auch:
val reader = BufferedReader(InputStreamReader(input))
try {
val results = StringBuilder()
while (true) {
val line = reader.readLine()
if (line == null) break
results.append(line)
}
val inputAsString = results.toString()
} finally {
reader.close()
}
Und selbst das sieht flüssiger aus, da es automatisch schließt InputStream
:
val inputString = BufferedReader(InputStreamReader(input)).useLines { lines ->
val results = StringBuilder()
lines.forEach { results.append(it) }
results.toString()
}
Oder eine leichte Variation davon:
val results = StringBuilder()
BufferedReader(InputStreamReader(input)).forEachLine { results.append(it) }
val resultsAsString = results.toString()
Dann dieses funktionale Faltding:
val inputString = input.bufferedReader().useLines { lines ->
lines.fold(StringBuilder()) { buff, line -> buff.append(line) }.toString()
}
Oder eine schlechte Variante, die das nicht schließt InputStream
:
val inputString = BufferedReader(InputStreamReader(input))
.lineSequence()
.fold(StringBuilder()) { buff, line -> buff.append(line) }
.toString()
Aber sie sind alle klobig und ich finde immer wieder neuere und unterschiedliche Versionen derselben ... und einige von ihnen schließen die nicht einmal InputStream
. Was ist eine nicht klobige (idiomatische) Art, das zu lesen InputStream
?
Hinweis: Diese Frage wurde absichtlich vom Autor geschrieben und beantwortet ( Selbst beantwortete Fragen ), sodass die idiomatischen Antworten auf häufig gestellte Kotlin-Themen in SO vorhanden sind.
use
oderuseLines
, die eine Blockfunktion für das ausführt, was "verwendet" wird.inputStream.useText { text -> ... }
Zum Beispiel erwarte ich beim Lesen von "readText" eine Funktion, die den Text zurückgibt :val inputAsString = inputStream.readText()
.