在Kotlin中将InputStream转换为String

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上结束了。