Recientemente vi código para leer el contenido completo de InputStream
una cadena en Kotlin, como:
// input is of type InputStream
val baos = ByteArrayOutputStream()
input.use { it.copyTo(baos) }
val inputAsString = baos.toString()
Y también:
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()
}
E incluso esto que parece más suave ya que cierra automáticamente el InputStream
:
val inputString = BufferedReader(InputStreamReader(input)).useLines { lines ->
val results = StringBuilder()
lines.forEach { results.append(it) }
results.toString()
}
O una ligera variación en ese:
val results = StringBuilder()
BufferedReader(InputStreamReader(input)).forEachLine { results.append(it) }
val resultsAsString = results.toString()
Entonces esta cosa de pliegue funcional:
val inputString = input.bufferedReader().useLines { lines ->
lines.fold(StringBuilder()) { buff, line -> buff.append(line) }.toString()
}
O una mala variación que no cierra el InputStream
:
val inputString = BufferedReader(InputStreamReader(input))
.lineSequence()
.fold(StringBuilder()) { buff, line -> buff.append(line) }
.toString()
Pero todos son torpes y sigo encontrando versiones más nuevas y diferentes de los mismos ... y algunos de ellos ni siquiera cierran el InputStream
. ¿Cuál es una forma no torpe (idiomática) de leer el InputStream
?
Nota: esta pregunta fue escrita y respondida intencionalmente por el autor ( Preguntas auto- respondidas ), de modo que las respuestas idiomáticas a los temas de Kotlin más frecuentes estén presentes en SO.
use
ouseLines
que ejecuta una función de bloque sobre lo que se está "usando". por ejemplo,inputStream.useText { text -> ... }
Por otra parte, cuando leí "READTEXT" Me espera una función que devuelve el texto:val inputAsString = inputStream.readText()
.