Я не получаю ожидаемого результата, используя readLine() в Java
Вопрос
Я использую фрагмент кода ниже, однако он работает не совсем так, как я понимаю.
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
try {
line = br.readLine();
while(line != null) {
System.out.println(line);
line = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Из чтения Javadoc о readLine()
там написано:
Читает строку текста.Строка считается завершенной любым из символов перевода строки (\n
), возврат каретки (\r
) или возврат каретки, за которым сразу следует перевод строки.
Возврат:А String
содержащий содержимое строки, не включая символы завершения строки, или ноль, если достигнут конец потока
Броски:
IOException
- Если возникает ошибка ввода-вывода
Насколько я понимаю это, readLine
должен возвращать ноль в первый раз, когда не вводится никакой ввод, кроме завершения строки, например \r
.Однако этот код просто зацикливается бесконечно.После отладки я обнаружил, что вместо возврата значения null при вводе только символа завершения на самом деле возвращается пустая строка ("").Для меня это не имеет смысла.Что я не правильно понимаю?
Решение
Насколько я понимаю, readLine должен возвращать значение null в первый раз, когда не вводится никакой ввод, кроме завершения строки, например ' '.
Это неправильно. readLine
вернется null
если достигнут конец потока.То есть, например, если вы читаете файл, и файл заканчивается, или если вы читаете из сокета, и сокет закрывается.
Но если вы просто читаете ввод с консоли, нажатие клавиши возврата на клавиатуре не означает окончания потока.Это просто возвращаемый символ (\n
или \r\n
в зависимости от вашей ОС).
Итак, если вы хотите разбить как пустую строку, так и конец строки, вам следует сделать:
while (line != null && !line.equals(""))
Кроме того, ваша текущая программа должна работать должным образом, если вы передаете какой-либо файл непосредственно в нее, например:
java -cp . Echo < test.txt
Другие советы
Отсутствие ввода — это не то же самое, что конец потока.Обычно вы можете имитировать конец потока в консоли, нажав Ctrl+Д (AFAIK некоторые системы используют Ctrl+З вместо).Но я думаю, это не то, что вам нужно, поэтому лучше проверяйте наличие пустых строк в дополнение к нулевым строкам.
Есть хороший язык Apache Commons библиотека, которая имеет хороший API для общих :) действий.Вы можете использовать статический импорт StringUtils и использовать его метод isNotEmpty(String), чтобы получить:
while(isNotEmpty(line)) {
System.out.println(line);
line = br.readLine();
}
Когда-нибудь это может пригодиться :) В этой библиотеке есть и другие полезные классы.