在Kotlin中,如何将InputStream的全部内容读入String?

时间:2016-09-14 21:40:10

标签: inputstream kotlin

我最近看到了将InputStream的全部内容读入Kotlin中的字符串的代码,例如:

// input is of type InputStream
val baos = ByteArrayOutputStream()
input.use { it.copyTo(baos) }
val inputAsString = baos.toString()

还有:

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()
}

即使这样看起来也更顺畅,因为它会自动关闭InputStream

val inputString = BufferedReader(InputStreamReader(input)).useLines { lines ->
    val results = StringBuilder()
    lines.forEach { results.append(it) }
    results.toString()
}

或者那个略有不同:

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

然后这个功能性的东西:

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

错误的变体,它不会关闭InputStream

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

但他们都很笨重,而且我一直在寻找相同的新版本和不同版本......其中一些甚至从未关闭InputStream。什么是非笨重(惯用)的方式来阅读InputStream

注意: 这个问题是由作者(Self-Answered Questions)故意编写和回答的,因此对于常见问题的Kotlin主题的惯用答案存在于SO中。

4 个答案:

答案 0 :(得分:163)

Kotlin只是为了这个目的而有一个特定的扩展。

最简单的:

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

在此示例中,您可以在bufferedReader()reader()之间做出决定。对函数Closeable.use()的调用将在lambda执行结束时自动关闭输入。

进一步阅读:

如果你经常做这类事情,你可以把它写成一个扩展函数:

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

然后您可以轻松调用:

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

在旁注中,所有需要知道charset默认为UTF-8的Kotlin扩展函数,因此如果您需要不同的编码,则需要在调用中调整上面的代码以包含编码适用于reader(charset)bufferedReader(charset)

警告:您可能会看到更短的示例:

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

但是这些不会关闭流。请务必检查您使用的API documentation for all of the IO functions,以确定哪些关闭,哪些关闭。通常,如果它们包含单词use(例如useLines()use()),则会在之后关闭流。一个例外是File.readText()Reader.readText()的不同之处在于前者不会留下任何东西,后者确实需要明确关闭。

另请参阅: Kotlin IO related extension functions

答案 1 :(得分:1)

将InputStream的内容读取为String

的示例
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)
}

供参考 - Kotlin Read File

答案 2 :(得分:0)

方法1 |手动关闭流}

private fun getFileText(uri: Uri):String {
    val inputStream = contentResolver.openInputStream(uri)!!

    val bytes = inputStream.readBytes()        //see below

    val text = String(bytes, StandardCharsets.UTF_8)    //specify charset

    inputStream.close()

    return text
}

方法2 |自动关闭流}

private fun getFileText(uri: Uri): String {
    return contentResolver.openInputStream(uri)!!.bufferedReader().use {it.readText() }
}

答案 3 :(得分:-1)

快速解决方案在将 InputStream 转换为字符串时效果很好。

val convertedInputStream = String(inputStream.readAllBytes(), StandardCharsets.UTF_8)