在Kotlin中,如何将InputStream的全部内容读入字符串?
我最近看到了将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()
然后这个功能折叠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
?
注意: 这个问题是由作者故意写的和回答的( 自我回答的问题 ),所以对于常见的Kotlin话题的习惯性的回答是在SO中。
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
Kotlin扩展函数已经默认为UTF-8
,所以如果你需要不同的编码,你需要调整上面的代码来调用reader(charset)
或者bufferedReader(charset)
。
警告:您可能会看到较短的示例:
val inputAsString = input.reader().readText()
但是这些不关闭流 。 确保你检查了所有你使用的IO函数的API文档,以确定哪些关闭,哪些不关闭。 通常如果他们包括词use
(比如useLines()
或者use()
),那么你关闭流之后。 File.readText()
与File.readText()
不同之处在于前者不保留任何开放,后者确实需要明确的关闭。
另请参阅: Kotlin IO相关的扩展功能
将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读取文件