InputStream to String in Kotlin
1.概述
在这个简短的教程中,我们将找到如何将InputStream读取为String。
Kotlin提供了执行转换的简便方法。但是,在使用资源时仍需要考虑一些细微差别。另外,我们还将介绍一些特殊情况,例如读取停止符。
2.缓冲读卡器
InputStream是围绕有序字节流的抽象。基础数据源可以是文件,网络连接或任何其他发出字节的源。让我们使用一个包含以下数据的简单文件:
1 2 | Computer programming can be a hassle It's like trying to take a defended castle |
我们可能尝试的第一个解决方案是逐行手动读取文件:
1 2 3 4 5 6 7 8 9 10 11 | val reader = BufferedReader(inputStream.reader()) val content = StringBuilder() try { var line = reader.readLine() while (line != null) { content.append(line) line = reader.readLine() } } finally { reader.close() } |
首先,我们使用BufferedReader类包装InputStream,然后读取直到流中没有剩余行。此外,我们用try-finally语句包围了读取逻辑,以最终关闭流。总共有很多样板代码。
我们可以使其更紧凑,更易读吗?
绝对!首先,我们可以使用readText()函数来简化代码段。它将输入流完全读取为String。因此,我们可以按以下方式重构代码段:
1 2 3 4 5 6 7 | val reader = BufferedReader(inputStream.reader()) var content: String try { content = reader.readText() } finally { reader.close() } |
但是,我们仍然有try-finally块。幸运的是,Kotlin允许以伪自动方式处理资源管理。让我们看下面的代码行:
1 2 | val content = inputStream.bufferedReader().use(BufferedReader::readText) assertEquals(fileFullContent, content) |
这种单线解决方案看起来很简单,但是在幕后发生了很多事情。上面代码中的一个重要点是use()函数的调用。此扩展功能在实现Closable接口的资源上执行一个块。最后,当执行该块时,Kotlin将为我们关闭资源。
3.停止字符
同时,在某些情况下,我们需要读取内容直到特定字符为止。让我们为InputStream类定义一个扩展函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 | fun InputStream.readUpToChar(stopChar: Char): String { val stringBuilder = StringBuilder() var currentChar = this.read().toChar() while (currentChar != stopChar) { stringBuilder.append(currentChar) currentChar = this.read().toChar() if (this.available() <= 0) { stringBuilder.append(currentChar) break } } return stringBuilder.toString() } |
此函数从输入流中读取字节,直到出现停止字符。同时,为了防止无限循环,我们调用available()方法来检查流中是否还有剩余数据。因此,如果流中没有停止符,则将读取整个流。
另一方面,并??非InputStream类的所有子类都提供available()方法的实现。因此,在使用扩展功能之前,我们必须确保正确实施该方法。
让我们回到示例中,读取直到第一个空格字符('')的文本:
1 2 | val content = inputStream.use { it.readUpToChar(' ') } assertEquals("Computer", content) |
结果,我们将使文本达到终止字符。同样,不要忘记使用use()函数包装该块以自动关闭流。
4。结论
在本文中,我们已经了解了如何在Kotlin中将InputStream转换为String。 Kotlin提供了一种处理数据流的简洁方法,但是始终值得了解内部发生了什么。
和往常一样,所有这些示例的实现都在Github上结束了。