139 votes

Dans Kotlin, comment lire l'intégralité du contenu d'un InputStream dans une chaîne?

J'ai récemment vu le code de lecture de tout le contenu d'un InputStream dans une Chaîne de Kotlin, tels 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 ce qui est plus lisse depuis l'auto-ferme l' 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-ci:

val results = StringBuilder()
BufferedReader(InputStreamReader(input)).forEachLine { results.append(it) }
val resultsAsString = results.toString()   

Alors cette fois fonctionnelle truc:

val inputString = input.bufferedReader().useLines { lines ->
    lines.fold(StringBuilder()) { buff, line -> buff.append(line) }.toString()
}

Ou un mauvais variation qui ne ferme pas l' InputStream:

val inputString = BufferedReader(InputStreamReader(input))
        .lineSequence()
        .fold(StringBuilder()) { buff, line -> buff.append(line) }
        .toString()

Mais ils sont tous maladroit et je continue de trouver les plus récents et les différentes versions de la même chose... et certains d'entre eux n'a même jamais fermer l' InputStream. Ce qui est un non-maladroit (idiomatiques) façon de lire l' InputStream?

Remarque: cette question est volontairement écrit et répondu par l'auteur (Auto-Répondu aux Questions), de sorte que le idiomatiques les questions les plus fréquemment posées Kotlin thèmes sont présents dans la.

287voto

Jayson Minard Points 5925

Kotlin est une des extensions spécifiques à cet effet.

Le plus simple:

val inputAsString = input.bufferedReader().use { it.readText() }  // defaults to UTF-8

Et dans cet exemple, vous pourriez décider entre bufferedReader() ou juste reader(). L'appel à la fonction Closeable.use() seront automatiquement la fermeture de l'entrée à la fin de la lambda exécution.

Pour en savoir plus:

Si vous faites ce genre de chose beaucoup, vous pourriez écrire cela comme une extension de la fonction:

fun InputStream.readTextAndClose(charset: Charset = Charsets.UTF_8): String {
    return this.bufferedReader(charset).use { it.readText() }
}

Qui vous peut ensuite appeler facilement que:

val inputAsString = input.readTextAndClose()  // defaults to UTF-8

Sur une note de côté, tous les Kotlin extension des fonctions qui nécessitent de savoir le charset déjà par défaut UTF-8, donc si vous avez besoin d'un codage différent, vous devez régler le code ci-dessus dans les appels d'inclure un encodage pour reader(charset) ou bufferedReader(charset).

Avertissement: Vous risquez de voir des exemples qui sont plus courtes:

val inputAsString = input.reader().readText() 

Mais ces ne pas fermer le flux de données. Assurez-vous que vous vérifiez la documentation de l'API pour l'ensemble de l'OI fonctions que vous utilisez pour être sûr de ceux qui sont proches et qui ne le font pas. Habituellement, si ils comprennent le mot use (comme useLines() ou use()) ton fermer le flux de données après. Une exception est qu' File.readText() diffère Reader.readText() en ce que la première ne rien laisser ouverte et ce dernier n'a en effet besoin d'un explicite à proximité.

Voir aussi: Kotlin IO liés à l'extension des fonctions de

2voto

Mallikarjun M Points 684

Un exemple qui lit le contenu d'un InputStream dans une chaîne

 import java.io.File
import java.io.InputStream
import java.nio.charset.Charset

fun main(args: Array<String>) {
    val file = File("input"+File.separator+"contents.txt")
    var ins:InputStream = file.inputStream()
    var content = ins.readBytes().toString(Charset.defaultCharset())
    println(content)
}
 

Pour référence - Fichier de lecture Kotlin

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X