Java 在Kotlin中使用BufferedReader的最佳方法

Java 在Kotlin中使用BufferedReader的最佳方法,java,bufferedreader,kotlin,Java,Bufferedreader,Kotlin,所以我刚刚开始在Android上使用Kotlin,并将我的Android Java代码转换成Kotlin 在其中一次转换中,我偶然发现了一个BufferedReader,我通常用Java编写它,如下所示: String result = ""; String line = ""; BufferedReader reader = new BufferedReader(someStream); while ( (line = reader.readLine()) != null ) { re

所以我刚刚开始在Android上使用Kotlin,并将我的Android Java代码转换成Kotlin

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

String result = "";
String line = "";
BufferedReader reader = new BufferedReader(someStream);
while ( (line = reader.readLine()) != null ) {
    result += line;
}
val reader = BufferedReader(someStream)
var line : String? = ""
while (line != null) {
    line = reader.readLine()
    result += line
}
但在Kotlin中,Kotlin似乎不允许我在while条件下为变量赋值

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

String result = "";
String line = "";
BufferedReader reader = new BufferedReader(someStream);
while ( (line = reader.readLine()) != null ) {
    result += line;
}
val reader = BufferedReader(someStream)
var line : String? = ""
while (line != null) {
    line = reader.readLine()
    result += line
}
尽管使用了Kotlin,但我觉得它并没有那么优雅,感觉上一代

在Kotlin中使用BufferedReader的最佳方式是什么?

您可以这样使用


如果您仍然想逐行阅读,可以使用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扩展函数将为您做到这一点

只是添加这些内容以供参考。。干杯

像这样使用代码

val input = conn.inputStream val allText = input.bufferedReader().use(BufferedReader::readText) val result = StringBuilder() result.append(allText) return result.toString() } else { return "unsuccessful" } val input=conn.inputStream val allText=input.bufferedReader().use(bufferedReader::readText) val result=StringBuilder() result.append(所有文本) 返回result.toString() }否则{ 返回“未成功” }
另一种方法是使用for循环:

val reader = BufferedReader(someStream)
for (line in reader.lines()) {
    println(line)
}
虽然它不像公认的答案那样简洁,但它将允许您循环通过并执行某种逻辑,而无需将所有内容泵入一个字符串,如下所示

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

多亏了João Gonçalves对stdlib的引用,我发现如果需要,您可以使用它来遍历阅读器。

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

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

有趣的读者。forEachLine(动作:(字符串)->单位)
遍历每个 此读卡器的行,为每行读取调用操作并关闭 读卡器,当它完成时


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

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

您可以像这样使用BufferReader:

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

不要像那样连接字符串。使用
StringBuilder.append()
。有表演issues@rafid059真正地我认为Java编译器(以及Kotlin编译器)会优化循环中的字符串连接。是的,Java编译器会将+=字符串concat转换为StringBuilder操作,但它在循环中,编译器无法优化循环部分。如果您使用
javap-cmain.class
分解此代码,那么您将在循环中看到一个StringBuilder实例。但每次都会创建一个新的stringbuilder,其中包含最新的
结果
,然后将
附加到它。太长,读不下去了编译器无法优化简单的for循环字符串连接。谢谢你的提示!解释:请注意:您可以使用
useLines()
方法迭代行,该方法返回一个延迟序列,然后为您关闭底层BufferedReader。是否
useLines
一次加载所有行?如果我试图从一个大文件中读取,会不会占用太多内存,或者每一行都是按需要提取的呢?提前感谢。因此,使用useLines使用一个序列,该序列在流上使用惰性求值,这有利于打开文件句柄计数:()。Jetbrains建议使用大型文件File.forEachLine,在该文件中一次只处理一行()。但是在封面下File.forEachLine仍然使用默认缓冲区大小为8*1024的useLines