#kotlin #exception #bufferedreader #filereader #try-with-resources
#котлин #исключение #bufferedreader #средство чтения файлов #попробуйте с ресурсами #filereader #попробуйте с помощью ресурсов
Вопрос:
Здесь я считываю строки консоли из текстового файла.
Я использую BufferedReader
и FileReader
classes
для этой цели.
Я также использую try-with-resources
функцию Java 7
Для достижения того же у меня есть следующий Java-код —
try (BufferedReader br = new BufferedReader(new FileReader(new File(filePath)))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("n");
}
} catch (FileNotFoundException e) {
System.out.printf("File not found: %sn", filePath);
noException = false;
} catch (IOException e) {
System.out.printf("File could not be read: %sn", filePath);
noException = false;
}
Теперь я хочу переписать тот же код, используя Kotlin. Я пытаюсь использовать следующий подход. Но, похоже, это не работает.
try(var br: BufferedReader = BufferedReader(FileReader(File(filePath))))
Итак, как правильно написать код в Kotlin?
Примечание:
Я хочу использовать только BufferedReader
, FileReader
подход, а не какой-либо другой подход.
Код Kotlin, к которому я пытаюсь применить try-with-resources
функцию Java 7, является —
var line: String? = ""
file = File(filePath)
try {
fr = FileReader(file)
br = BufferedReader(fr)
while (line != null) {
line = br!!.readLine()
if (line != null) {
sb.append(line).append("n")
}
}
} catch (e: FileNotFoundException) {
println("File not found: $filePath")
noException = false
} catch (e: IOException) {
println("File could not be read: $filePath")
noException = false
}
finally {
try {
br!!.close()
} catch (e: IOException) {
//
noException = false
} catch (e: NullPointerException) {
//
noException = false
}
}
Цель использования try-with-resources
функции — сократить код
Ответ №1:
По дизайну Kotlin не имеет языковой конструкции, подобной try-with-resources
в Java.
Вместо этого мы можем найти метод расширения, вызываемый use
в его стандартной библиотеке.
use
Ключевое слово может быть применено к приведенному выше коду следующим образом —
try {
val br: BufferedReader = BufferedReader(FileReader(File(filePath)))
br.use {
while (line != null) {
line = br.readLine()
if (line != null) {
sb.append(line).append("n")
}
}
}
} catch (e: FileNotFoundException) {
println("File not found: $filePath")
noException = false
} catch (e: IOException) {
println("File could not be read: $filePath")
noException = false
}
Определение use()
в Kotlin, как найдено в его стандартной библиотеке:
общедоступная встроенная функция <T : Закрываемая?, R> T.использование(блок: (T) -> R): R
Мы можем видеть в части <T : Closeable?, R>, что use определяется как функция расширения в интерфейсе Java Closeable.
Комментарии:
1. Ммм,
use()
это стандартный подход для чтения и записи файлов в Kotlin. (На самом деле, во многих случаях вы даже не стали бы беспокоиться обtry
…catch
этом, а вместо этого передали бы его прямо вызывающему.)2. Можно выполнить дополнительные упрощения: вместо того, чтобы вызывать
use()
, а затемreadLine()
в цикле, было бы лучше вызватьuseLines()
; вы можете вызватьforEach()
результат этого, илиmap()
или в данном случае простоjoinToString()
. Кроме того, если бы у меня еще не былоFile
объекта, я бы не стал создавать его, а просто использовалString
перегрузкуFileReader()
конструктора.3. @gidds Я с платформы Java, совершенно не знаю о Kotlin. Мой путь обучения — следовать руководству по Java для начинающих и переводить каждый Java-код в код Kotlin.
4. Это была не критика, а указатель на то, как вы могли бы улучшить свой ответ 🙂