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.
fuente
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()
.use
funciones en ese sentido. al menos en el contexto de estas preguntas y respuestas. tal vez se pueda encontrar un nuevo verbo ...readTextAndClose()
este ejemplo para evitar conflictos con losreadText()
patrones de no cerrar y con losuse
patrones que quieren una lambda, ya que no estoy tratando de introducir una nueva función stdlib, no quiero hacer más que señalar el uso extensiones para ahorrar mano de obra futura.Un ejemplo que lee el contenido de un InputStream en un String
Para referencia: archivo de lectura de Kotlin
fuente
Paths.get()
método. 2) Para transmisiones: función try-resource (en kotlin: .use {})