2016-12-06 23 views
6

Tak więc właśnie zacząłem używać Kotlin dla Androida (w nadziei, że to też może mi pomóc z Swift) i przekonwertowałem kody Java Java na Kotlin.Najlepszy sposób na użycie BufferedReader w Kotlin

W jednym z konwersjami, natknąłem się na BufferedReader, które zazwyczaj piszę w Javie (lub raczej C#) jak następuje:

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

Ale w Kotlin, wydaje się, że Kotlin nie pozwól mi przypisać wartości do zmiennych w warunkach while.

Obecnie Pisałem kod jak:

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

który nie znajdę tak eleganckie (i prev-gen, mimo korzystania Kotlin).

Jaki byłby najlepszy sposób użycia BufferedReader w Kotlin?

+1

Nie łącz takich ciągów. Użyj 'StringBuilder.append()'. Występują problemy z wydajnością – rafid059

+0

@ rafid059 Naprawdę? Myślałem, że kompilatory Java (a więc kompilator Kotlin) optymalizują konkatenacje ciągów w pętlach. –

+1

Tak, kompilator java konwertuje konkord ciąg znaków + = na operację StringBuilder, ale tutaj znajduje się wewnątrz pętli, a kompilator nie może zoptymalizować części pętli. Jeśli ześlesz ten kod za pomocą 'javap -c Main.class', zobaczysz instancję StringBuilder wewnątrz pętli. Ale nowy konstruktor stringów jest tworzony za każdym razem z najnowszym 'result', a następnie dołączany jest do niego' line'. ** TLDR; ** kompilator nie może zoptymalizować prostej konkatenacji ciągów w pętli – rafid059

Odpowiedz

18

Można użyć bufferedReader jak tak

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

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

3

Jeśli nadal chciał ją przeczytać wiersz po wierszu można użyć pewnych funkcji rozszerzających z std lib i zrobić to w następujący sposób:

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

lub alternatywnie, używając "funkcjonalnego" podejścia:

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

za pomocą UseLines, nie jesteś t musisz jawnie wywołać zamknięcie na czytniku, funkcja rozszerzenia UseLines zrobi to za Ciebie!

Po prostu dodawanie ich dla odniesienia .. Pozdrawiam

Powiązane problemy