首页 文章

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

提问于
浏览
54

我最近看到了用于将 InputStream 的全部内容读入Kotlin中的String的代码,例如:

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

或者 bad 变体没有关闭 InputStream

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

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

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

2 回答

  • 132

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

    The simplest:

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

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

    Further reading:

    如果你做了很多类型的事情,你可以把它写成一个扩展函数:

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

    然后您可以轻松调用:

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

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

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

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

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

    See also: Kotlin IO related extension functions

  • 0

    将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

相关问题