在Kotlin中,如何将InputStream的全部内容读取为String? [英] In Kotlin, how do I read the entire contents of an InputStream into a String?

查看:499
本文介绍了在Kotlin中,如何将InputStream的全部内容读取为String?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I recently saw code for reading entire contents of an InputStream into a String in Kotlin, such as:

// 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:

And even this that looks smoother since it auto-closes the InputStream:

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

或在那一个上略有变化:

Or slight variation on that one:

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

然后这个功能折叠很重要:

Then this functional fold thingy:

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的非笨拙(惯用)方式是什么?

But they are all clunky and I keep finding newer and different versions of the same... and some of them never even close the InputStream. What is a non-clunky (idiomatic) way to read the InputStream?

注意: 该问题是作者故意写并回答的(

Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that the idiomatic answers to commonly asked Kotlin topics are present in SO.

推荐答案

Kotlin为此具有特定的扩展名.

Kotlin has a specific extensions just for this purpose.

最简单的

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

在本例中,您可以在bufferedReader()reader()之间做出选择.对函数 Closeable.use() 的调用将在最后自动关闭输入lambda的执行情况.

And in this example you could decide between bufferedReader() or just reader(). The call to the function Closeable.use() will automatically close the input at the end of the lambda's execution.

进一步阅读:

如果您经常执行此类操作,则可以将其编写为扩展函数:

If you do this type of thing a lot, you could write this as an extension function:

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

随后您可以轻松拨打以下电话:

Which you could then call easily as:

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

附带说明,所有需要了解charset的Kotlin扩展功能已经默认为UTF-8,因此,如果您需要其他编码,则需要在调用中调整上面的代码以包含reader(charset)的编码或bufferedReader(charset).

On a side note, all Kotlin extension functions that require knowing the charset already default to UTF-8, so if you require a different encoding you need to adjust the code above in calls to include an encoding for reader(charset) or bufferedReader(charset).

警告:您可能会看到一些简短的示例:

Warning: You might see examples that are shorter:

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

但是这些不会关闭信息流.确保检查用于所有IO功能的 API文档确保哪些关闭,哪些不关闭.通常,如果它们包含单词use(例如useLines()use()),则请在之后关闭流.一个例外是 File.readText() Reader.readText() 不同前者没有任何开放,而后者确实需要显式关闭.

But these do not close the stream. Make sure you check the API documentation for all of the IO functions you use to be sure which ones close and which do not. Usually if they include the word use (such as useLines() or use()) thy close the stream after. An exception is that File.readText() differs from Reader.readText() in that the former does not leave anything open and the latter does indeed require an explicit close.

另请参见:与Kotlin IO相关的扩展功能

这篇关于在Kotlin中,如何将InputStream的全部内容读取为String?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆