在 Kotlin 中使用 BufferedReader 的最佳方式

Posted

技术标签:

【中文标题】在 Kotlin 中使用 BufferedReader 的最佳方式【英文标题】:Best way to use BufferedReader in Kotlin 【发布时间】:2017-04-21 09:36:26 【问题描述】:

所以我刚刚开始使用 Kotlin for android,并将我的 Android Java 代码转换为 Kotlin。

在一次转换中,我偶然发现了一个 BufferedReader,我通常会用 Java 编写如下:

String result = "";
String line = "";
BufferedReader reader = new BufferedReader(someStream);
while ( (line = reader.readLine()) != null ) 
    result += line;

但在 Kotlin 中,似乎 Kotlin 不允许我在 while 条件下为变量赋值。

目前,我编写的代码如下:

val reader = BufferedReader(someStream)
var line : String? = ""
while (line != null) 
    line = reader.readLine()
    result += line

尽管使用了 Kotlin,但我觉得它并没有那么优雅并且感觉上一代。

是什么?

【问题讨论】:

【参考方案1】:

你可以像这样使用bufferedReader

val allText = inputStream.bufferedReader().use(BufferedReader::readText)

【讨论】:

解释:kotlinlang.org/docs/reference/…【参考方案2】:

如果您仍想逐行阅读,可以使用 std lib 中的一些扩展函数并按如下方式进行:

val reader = someStream.bufferedReader()
val iterator = reader.linesSequences().iterator()
while(iterator.hasNext()) 
    val line = iterator.next()
    // do something with line...

reader.close()

或者,使用“功能”方法:

val reader = someStream.bufferedReader()
reader.useLines 
    it.map  line -> // do something with line 

通过使用 useLines,您无需在阅读器上显式调用 close,useLines 扩展函数将为您完成!

只是添加这些以供参考.. 干杯

【讨论】:

useLines 是否一次加载所有行?如果我试图从一个大文件中读取,这会使用太多内存还是每行都根据需要获取?提前致谢。 因此 useLines 使用了一个序列,该序列对流进行惰性求值,这有利于打开文件句柄计数:(kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/…)。 Jetbrains 建议大文件 File.forEachLine 一次使用一行 (kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-file/…)。但在幕后 File.forEachLine 仍然使用 useLines,默认缓冲区大小相同,为 8 * 1024【参考方案3】:

您也可以尝试使用“forEachLine”方法。

val file = File("./folder/test.txt")
file.bufferedReader().forEachLine 
    println("value = $it")
 

它还会在读取最后一行后自动关闭流

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-reader/index.html

fun Reader.forEachLine(action: (String) -> Unit) 遍历每个 此阅读器的行,为读取的每一行调用操作并关闭 完成后的阅读器。

【讨论】:

【参考方案4】:

另一种方法是使用for循环:

val reader = BufferedReader(someStream)
for (line in reader.lines()) 
    println(line)

虽然它不像公认的答案那么简洁,但它可以让您循环并执行某种逻辑,而无需将所有内容都抽到一个字符串中,如下所示

val allText: String = inputStream.bufferedReader().use(BufferedReader::readText)

【讨论】:

请注意:您可以使用useLines() 方法迭代行,该方法返回一个惰性序列,然后为您关闭底层的 BufferedReader。【参考方案5】:

感谢 João Gonçalves 对 stdlib 的引用,我发现如果需要,您可以使用 forEachLine 遍历阅读器。

【讨论】:

【参考方案6】:

使用这样的代码

val 输入 = conn.inputStream val allText = input.bufferedReader().use(BufferedReader::readText) val 结果 = StringBuilder() 结果.append(allText) 返回结果.toString() 别的 返回“不成功”

【讨论】:

【参考方案7】:

当流有多行时,接受的答案失败。这是我的解决方案

val allText = inputStream.bufferedReader().use  it.readLines().joinToString("") 

【讨论】:

【参考方案8】:

你可以像这样使用 BufferReader :

val data = inputStream.bufferedReader().use(BufferedReader::readText)
    

【讨论】:

您的解决方案与接受的答案有何不同?

以上是关于在 Kotlin 中使用 BufferedReader 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

使用 Kotlin 提高生产力

使用java获取计算机中硬盘的真实序列号

如何在Kotlin中使用Gradle构建缓存?

如何在 Kotlin Multiplatform(纯 kotlin)中进行延迟

如何在 Kotlin 中使用 ViewModelProviders

如何在 kotlin 中使用片段