J'ai récemment vu du code pour lire le contenu entier d'un InputStream
dans une chaîne dans Kotlin, tel que:
// input is of type InputStream
val baos = ByteArrayOutputStream()
input.use { it.copyTo(baos) }
val inputAsString = baos.toString()
Et aussi:
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()
}
Et même celui-ci qui semble plus lisse car il ferme automatiquement le InputStream
:
val inputString = BufferedReader(InputStreamReader(input)).useLines { lines ->
val results = StringBuilder()
lines.forEach { results.append(it) }
results.toString()
}
Ou une légère variation sur celui-là:
val results = StringBuilder()
BufferedReader(InputStreamReader(input)).forEachLine { results.append(it) }
val resultsAsString = results.toString()
Ensuite, ce truc de pli fonctionnel:
val inputString = input.bufferedReader().useLines { lines ->
lines.fold(StringBuilder()) { buff, line -> buff.append(line) }.toString()
}
Ou une mauvaise variation qui ne ferme pas le InputStream
:
val inputString = BufferedReader(InputStreamReader(input))
.lineSequence()
.fold(StringBuilder()) { buff, line -> buff.append(line) }
.toString()
Mais ils sont tous maladroits et je continue à trouver des versions plus récentes et différentes du même ... et certains d'entre eux ne ferment même jamais le InputStream
. Qu'est-ce qu'une façon non maladroite (idiomatique) de lire le InputStream
?
Remarque: cette question est intentionnellement écrite et répondue par l'auteur ( Questions auto-répondues ), de sorte que les réponses idiomatiques aux sujets Kotlin fréquemment posées soient présentes dans SO.
la source
use
ouuseLines
qui exécute une fonction de bloc sur ce qui est "utilisé". par exemple , d'inputStream.useText { text -> ... }
autre part, quand je lis « readText » Je me attends à une fonction qui renvoie le texte:val inputAsString = inputStream.readText()
.use
fonctions à cet égard. au moins dans le contexte de ce Q&R. peut-être qu'un nouveau verbe peut être trouvé ...readTextAndClose()
cet exemple pour éviter les conflits avec lesreadText()
modèles de non fermeture, et avec lesuse
modèles voulant un lambda, puisque je n'essaye pas d'introduire une nouvelle fonction stdlib, je ne veux pas faire plus que faire un point sur l'utilisation extensions pour économiser le travail futur.Un exemple qui lit le contenu d'un InputStream dans une chaîne
Pour référence - Fichier de lecture Kotlin
la source
Paths.get()
méthode. 2) Pour les flux - fonctionnalité try-resource (Dans kotlin: .use {})