Читать все строки с помощью BufferedReader

Я хочу напечатать текст с несколькими строками в консоли, используя BufferedReader, и когда я ударил "Enter", чтобы найти сумму длины всего текста. Проблема в том, что кажется, что я попадаю в бесконечный цикл, и когда я нажимаю "Enter", программа не подходит к концу. Мой код ниже:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

    line= buffer.readLine();

    while (line!=null){
        length = length + line.length();
        line= buffer.readLine();
    }

Не могли бы вы рассказать мне, что я делаю неправильно?

Ответы

Ответ 1

Идиоматический способ чтения всех строк - while ((line = buffer.readLine()) != null). Кроме того, я бы предложил try-with-resources statement. Что-то вроде

try (InputStreamReader instream = new InputStreamReader(System.in);
        BufferedReader buffer = new BufferedReader(instream)) {
    long length = 0;
    String line;
    while ((line = buffer.readLine()) != null) {
        length += line.length();
    }
    System.out.println("Read length: " + length);
} catch (Exception e) {
    e.printStackTrace();
}

Если вы хотите закончить цикл, когда получаете пустую строку, добавьте тест для этого в цикле while

while ((line = buffer.readLine()) != null) {
    if (line.isEmpty()) {
        break;
    }
    length += line.length();
}

JLS-14.15. В заявлении break говорится:

Оператор

A break передает управление из прилагаемого оператора.

Ответ 2

одна строка кода с использованием java8

line = buffer.lines().collect(Collectors.joining());

Ответ 3

line не будет пустым, когда вы нажмете enter; это будет пустая строка.

Обратите внимание, что BufferedReader JavaDoc говорит о readLine():

Считывает текст. Линия считается завершенной любым из строк ('\n'), возвратом каретки ('\ r') или возвратом каретки, за которым следует сразу строка.

И readLine() возвращает:

A Строка, содержащая содержимое строки, не включая символы окончания строки, или null, если конец потока достигнут

Итак, когда вы нажимаете [Enter], вы даете BufferedReader новую строку, содержащую только \n, \r или \r\n. Это означает, что readLine() вернет пустую строку.

Итак, попробуйте что-то вроде этого:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

line = buffer.readLine();

while( (line != null) && (!line.isEmpty()) ){
    length = length + line.length();
    line = buffer.readLine();
}

Ответ 4

Когда вы только нажимаете Enter, возврат из buffer.readLine(); не равен null, это пустая строка.

Поэтому вы должны изменить line != null на !line.equals("") (вы также можете изменить его на line.length() > 0)

Теперь ваш код будет выглядеть примерно так:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

line = buffer.readLine();

while (!line.equals("")){
    length = length + line.length();
    line = buffer.readLine();
}

Это должно решить вашу проблему. Надеюсь, это помогло!:)

Ответ 5

Snarky ответ: то, что вы делаете неправильно, создает только 2 объекта в Java, чтобы что-то делать... если вы ищете, вы, вероятно, можете найти еще несколько классов, которые расширяют BufferedReader или ExtendedBufferReader и т.д., а затем это может быть реальной Enterprise Java.

Теперь, когда я получил это из своей системы: более полезный ответ. System.in закрывается, когда вы вводите EOF, который является Control-D под Linux, и я думаю, что MacOS, и я думаю, Control-Z plus входит под Windows. Если вы хотите проверить ввод (или, более конкретно, два входа... один для завершения последней строки и один, чтобы указать, что вы закончили, что по сути является тем, как http обрабатывает определение, когда заголовки http завершены, и это время для тело http, тогда решение @dbank должно быть жизнеспособным вариантом с незначительным исправлением, которое я собираюсь сделать, чтобы переместить внутри внутри предиката вместо. while.

(Edit # 2: реализованная readLine перетаскивает новую строку, поэтому пустая строка будет "" вместо новой строки, поэтому теперь мой код переходит к другому ответу с битом EOF в качестве ответа вместо комментария)

Изменить... это странно, @dbank ответил, когда я печатал свой ответ, и я бы остановился, если бы не упоминал альтернативу EOF. Чтобы повторить его код из памяти с редактированием, которое я собирался сделать:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

    line= buffer.readLine();
    while (line != null && !line.equals("")){
        length = length + line.length();
        line= buffer.readLine();
    }

Ответ 6

Так как Java 8 можно использовать метод BufferedReader#lines непосредственно на буферизованном считывателе.

    try (InputStreamReader in = new InputStreamReader(System.in);
         BufferedReader buffer = new BufferedReader(in)) {
        final int length = buffer.lines().mapToInt(String::length).sum();
        System.out.println("Read length: " + length);
    } catch (Exception e) {
        e.printStackTrace();
    }