Читать все строки с помощью 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();
}