Чтение строк из текстового файла в консоль с помощью BufferedReader и FileReader и применение try-with-resources в Kotlin

#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. Это была не критика, а указатель на то, как вы могли бы улучшить свой ответ 🙂