Kotlin中的bufferedReader()方法是如何工作的?

7

我正在尝试在我的Android项目中从一个.json文件中读取数据:

val file = context.assets.open("myfile.json").bufferedReader().readText()

这段代码可以顺利地将我的.json文件以一个String的形式打印出来。
然而,我想知道bufferedReader()到底是什么以及为什么不能直接在打开的.json文件上调用.readText()
附注:readText()返回一个String。不过,val json2: JSONObject = JSONObject("mystring")的返回结果是:
Caused by: org.json.JSONException: Value mystring of type java.lang.String cannot be converted to JSONObject

这有什么意义吗?
2个回答

7

readText 函数是在 Reader 扩展上定义的:

public fun Reader.readText(): String {
    val buffer = StringWriter()
    copyTo(buffer)
    return buffer.toString()
}

InputStream 并不是 Reader,因此您需要将其转换为某个 Reader

public inline fun InputStream.reader(charset: Charset = Charsets.UTF_8): InputStreamReader = 
    InputStreamReader(this, charset)

您可以使用替代的 bufferedReader 函数将阅读器用作缓冲阅读器:
public inline fun InputStream.bufferedReader(charset: Charset = Charsets.UTF_8): BufferedReader = 
    reader(charset).buffered()
ReaderBufferedReader是Java标准库的一部分,其中缓冲版本的描述如下:

从字符输入流中读取文本,缓冲字符以提供对字符、数组和行的高效读取。

通常情况下,对Reader发出的每个读取请求会导致底层字符或字节流发出相应的读取请求。因此,建议在任何可能耗费read()操作的Reader周围包装一个BufferedReader,例如FileReaders和InputStreamReaders...

它基本上包装了一个Reader并添加了对读取单行等内容的支持。

5
val file = context.assets.open("myfile.json").bufferedReader().readText()

这是执行与上述行相同操作的代码。

val inputStream = context.assets.open("myfile.json")
val reader = inputStream.bufferedReader()
val file = reader.readText()

假设这里是myfile.json的内容。
{
    "os": "Android",
    "version": "KitKat",
    "codeName": 4.4
}

让我们一步一步来

步骤1:第一行

val inputStream = context.assets.open("myfile.json")

这将返回一个InputStream对象,它从json文件中读取一个字节或多个字节。如果在屏幕上以字节格式打印json文件内容,对于我们(作为程序员)来说阅读起来会非常困难。
第二行。
val reader = inputStream.bufferedReader()

这将创建一个BufferedReader对象,它从json文件中读取一个字符或多个字符,但它们还有另一个有用的方法readLine(), 这个方法读取一行文本。行被认为是由换行符('\n')、回车符('\r')或回车符后紧接着换行符之一终止的。
让我们修改当前的代码。
val inputStream = context.assets.open("myfile.json")
val reader = inputStream.bufferedReader()

// Read line by line from reader until reach the end.
var line = reader.readLine()
while(line != null) {
    Log.i("TAG", line)
    line = reader.readLine()
}

输出:

I/TAG: {
I/TAG:     "os": "Android",
I/TAG:     "version": "KitKat",
I/TAG:     "codeName": 4.4
I/TAG: }

我们可以看到,他们从json文件中打印了5行。但在某些情况下,我们希望将整个json文件作为字符串打印出来,这就是我们进入下一步的原因。
第三行:
val file = reader.readText()

这将完全读取缓冲读取器作为字符串。您可以编写自己的代码来实现相同的功能。
val inputStream = context.assets.open("myfile.json")
val reader = inputStream.bufferedReader()

val sb = StringBuffer()

var line = reader.readLine()
while(line != null) {
    Log.i("TAG", line)
    sb.append(line).append("\n")
    line = reader.readLine()
}

val file = sb.toString()

Log.i("TAG", file)

输出:

I/TAG: {
        "os": "Android",
        "version": "KitKat",
        "codeName": 4.4
}

这个输出与reader.readText()相同。
结论:BufferReader将InputStream(或InputStream的子类)包装在其中,然后提供逐字符读取而不是逐字节读取InputStream的方法。此外,它们提供readLine()方法和缓冲数据。

InputStream(逐字节) -> Reader(逐字符)

InputStream(逐字节) -> BufferReader(逐字符,读行,缓冲数据)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接