2016-12-06 367 views
6

所以我刚开始使用Kotlin for Android(希望它可以帮助我使用Swift),并将我的Android Java代码转换为Kotlin。在Kotlin中使用BufferedReader的最佳方式

在转换的一个,我偶然发现了一个BufferedReader,我会在Java中(或者更确切地说,C#),通常写为如下:

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

但在科特林,似乎科特林不允许我在while条件中给变量赋值。

目前,我写的代码如下所示:

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

,我不觉得那么优雅(和prev根,尽管使用科特林)。

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

+1

不要连接这样的字符串。使用'StringBuilder.append()'。有性能问题 – rafid059

+0

@ rafid059真的吗?我认为Java编译器(以及Kotlin编译器)优化了循环中的字符串连接。 –

+1

是的,java编译器将一个+ =字符串concat转换为一个StringBuilder操作,但在这里它是在一个循环中,编译器不能优化循环部分。如果你使用'javap -c Main.class'来解析这段代码,那么你会在循环中看到一个StringBuilder实例。但是每次使用最新的'result'创建一个新的stringbuilder,然后'line'被追加到它。 ** TLDR; **编译器无法优化简单的for-loop字符串连接 – rafid059

回答

18

您可以使用bufferedReader像这样

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

解释:https://kotlinlang.org/docs/reference/idioms.html#java-7s-try-with-resources – voddan

3

如果你仍然想逐行读它,你可以使用一些扩展功能,从标准库,并做如下:

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,你不' t需要在阅读器上明确地调用close,useLines扩展函数将为您做到这一点!

只需添加参考..干杯