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.
quelle
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()
.use
Funktionen in dieser Hinsicht entspricht. Zumindest im Zusammenhang mit diesen Fragen und Antworten. Vielleicht kann ein neues Verb gefunden werden ...readTextAndClose()
für dieses Beispiel entschieden, um Konflikte mitreadText()
Mustern zu vermeiden , die nicht geschlossen werden, und mituse
Mustern, die ein Lambda wollen, da ich nicht versuche, eine neue stdlib-Funktion einzuführen, möchte ich nicht mehr tun, als einen Punkt über die Verwendung zu machen Erweiterungen, um zukünftige Arbeitskräfte zu sparen.Ein Beispiel, das den Inhalt eines InputStream in einen String liest
Als Referenz - Kotlin Read File
quelle
Paths.get()
Methode verwenden. 2) Für Streams - Try-Resource-Funktion (In Kotlin: .use {})