所以我试图从我的Android项目中的.json
文件中读取数据:
val file = context.assets.open("myfile.json").bufferedReader().readText()
这很好,并成功打印出我的.json
文件作为一个String
。
但是我想知道究竟是什么bufferedReader()
以及为什么.readText()
不能直接在打开的.json
文件上调用。
PS:readText()
返回String
。然而:
val json2: JSONObject = JSONObject("mystring")
回归:
Caused by: org.json.JSONException: Value mystring of type java.lang.String cannot be converted to JSONObject
这有什么意义?
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()
Reader
和BufferedReader
是Java标准库的一部分,缓冲版本如下所述:
从字符输入流中读取文本,缓冲字符,以便有效地读取字符,数组和行。
通常,由Reader构成的每个读取请求都会导致相应的读取请求由基础字符或字节流构成。因此,建议在读取()操作成本高昂的任何Reader周围包装BufferedReader,例如FileReaders和InputStreamReaders ......
它基本上包裹了Reader
并增加了对单行读取等的支持。
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文件内容,我们(作为程序员)将很难阅读。
第2步:第二行
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文件打印为String,这就是我们进入下一步的原因。
第3步:第三行
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(逐个字符,读取行,缓冲区数据)。