ReadLine: примеры (JAVA)
readLine: StringОбщее описание метода readLine
В Java метод readLine встречается в нескольких классах ввода-вывода и служит для чтения текста построчно. Наиболее часто используется в java.io.BufferedReader.readLine() и java.io.Console.readLine(). Поведение зависит от конкретного класса-реализации, но общая идея - вернуть следующую строку без символа новой строки или null при достижении конца потока.
Ключевые варианты:
- BufferedReader.readLine() - не принимает аргументов; возвращает
Stringилиnull; объявляетthrows IOException. Читает последовательность символов до '\n', '\r' или '\r\n' и не включает символы перевода строки в возвращаемую строку. - Console.readLine() - перегружен:
readLine()иreadLine(String fmt, Object... args); возвращаетStringилиnullесли консоль недоступна; может форматировать приглашение; не бросает проверяемого исключения IOException. - DataInputStream.readLine() - устарел (deprecated). Возвращает
Stringи считывает байты, преобразует их в символы без учета кодировки; не рекомендуется к использованию.
Возвращаемые значения и ошибки:
- Возвращает
Stringс содержимым строки без символов конца строки. - Возвращает
nullпри достижении конца потока. - В
BufferedReaderвозможенIOException, вConsoleдоступ к консоли может бытьnullв GUI/IDE.
Рекомендации по использованию: для файлов и сетевых потоков предпочтение отдается BufferedReader (в связке с InputStreamReader и явной кодировкой). Для интерактивной консоли удобен Console, а для простого разбора токенов - Scanner с nextLine().
Короткие примеры использования
Пример 1 - чтение строки с BufferedReader из System.in:
import java.io.*;
public class Example1 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, "UTF-8"));
System.out.print("Введите текст: ");
String line = br.readLine();
System.out.println("Введено: " + line);
}
}
(ввод: Привет) Введено: Привет
Пример 2 - Console.readLine с приглашением (если запущено в консоли):
import java.io.Console;
public class Example2 {
public static void main(String[] args) {
Console console = System.console();
if (console == null) {
System.out.println("Консоль недоступна");
return;
}
String name = console.readLine("Имя: ");
System.out.println("Привет, " + name);
}
}
(если доступна консоль, ввод: Анна) Привет, Анна (если консоль недоступна) Консоль недоступна
Пример 3 - чтение всех строк из файла:
import java.io.*;
public class Example3 {
public static void main(String[] args) throws Exception {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String s;
while ((s = br.readLine()) != null) {
System.out.println(s);
}
}
}
}
(содержимое test.txt: Hello\nWorld) Hello World
Пример 4 - устаревший DataInputStream.readLine (не рекомендуется):
// Не рекомендуется к использованию
import java.io.*;
public class Example4 {
public static void main(String[] args) throws Exception {
DataInputStream dis = new DataInputStream(System.in);
String s = dis.readLine();
System.out.println(s);
}
}
(работает, но игнорирует кодировки и помечен как deprecated)
Похожие Java-методы и их особенности
- Scanner.nextLine() - возвращает строку до конца текущей строки; удобен для разбора токенов и примитивов с автоматическим разбором типов. Менее эффективен по памяти, чем BufferedReader при больших объемах.
- Files.lines(Path) (Java 8+) - возвращает Stream<String> для построчной обработки в функциональном стиле; поддерживает ленивую обработку и параллели при необходимости.
- BufferedReader.lines() - возвращает Stream<String> аналогично Files.lines, удобен для цепочек фильтрации/маппинга.
- LineNumberReader.readLine() - наследник BufferedReader с поддержкой номера строки через getLineNumber().
Выбор зависит от задачи: для простого и быстрого чтения больших файлов - BufferedReader или Files.lines; для интерактивного ввода с форматированием - Console; для парсинга - Scanner.
Аналоги в других языках и отличия
PHP:
// fgets с STDIN
$line = fgets(STDIN);
echo $line;
(ввод: Привет) Привет
JavaScript (браузер):
// prompt в браузере
const s = prompt('Введите:');
console.log(s);
(ввод через диалог) Выведено в консоль введённое значение
Node.js:
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
rl.question('Введите: ', (answer) => { console.log(answer); rl.close(); });
(ввод: Тест) Тест
Python:
# input() возвращает строку без конца строки
s = input('Введите: ')
print(s)
(ввод: Привет) Привет
SQL:
Чтение строк с консоли специфично для клиента СУБД; в SQL нет встроенной функции readLine в языке запросов. В процедурных расширениях (PL/pgSQL) используются параметры и функции ввода в клиенте.
C#:
// Console.ReadLine()
using System;
class C { static void Main(){ string s = Console.ReadLine(); Console.WriteLine(s);} }
(ввод: Тест) Тест
Lua:
local s = io.read()
print(s)
(ввод: hello) hello
Go:
// bufio.Reader
package main
import ("bufio"; "fmt"; "os")
func main(){ r := bufio.NewReader(os.Stdin); s, _ := r.ReadString('\n'); fmt.Print(s) }
(ввод: hi) hi
Kotlin:
fun main(){ val s = readLine(); println(s) }
(ввод: Привет) Привет
Отличия от Java:
- Во многих языках чтение строки возвращает пустую строку при пустом вводе и не бросает IOException, тогда как в Java BufferedReader объявляет checked-исключение.
- Кодировка требует явного указания в Java при работе с байтовыми потоками, в некоторых языках (Python 3, Kotlin) кодировка управляется средой выполнения более прозрачно.
- Наличие потоков и ленивой обработки: Java предоставляет Streams (Files.lines), Go/Node используют собственные асинхронные модели.
Типичные ошибки при использовании
- Игнорирование проверки на
null. При достижении EOFreadLine()возвращаетnull, последующая операция с результатом без проверки вызываетNullPointerExceptionпри использовании методов строки.
BufferedReader br = new BufferedReader(new FileReader("empty.txt"));
String s = br.readLine();
int len = s.length(); // потенциальная NPE
Exception in thread "main" java.lang.NullPointerException at ...
System.console() может вернуть null в IDE или при перенаправленном вводе.Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String rest = sc.nextLine(); // прочитает остаток строки после числа
(ввод: 5\nHello\n) rest будет пустой строкой, а не "Hello"
Изменения и статус в современных версиях Java
- BufferedReader.readLine() сохраняет прежнюю сигнатуру и семантику; существенных изменений в API метода в последних версиях Java не происходило.
- DataInputStream.readLine() давно помечен как deprecated и не рекомендуется к применению из-за проблем с кодировками.
- В Java 8 добавлены потоки для построчной обработки:
BufferedReader.lines()иFiles.lines(), что предоставляет более гибкие и декларативные способы работы с построчным вводом. - Console по-прежнему зависит от окружения; в модульных и контейнерных сценариях доступ к консоли может быть ограничен.
Расширенные и редко встречающиеся примеры
Пример 1 - чтение файла с явной кодировкой и подсчёт строк, содержащих шаблон:
import java.io.*;
import java.util.regex.*;
public class Adv1 {
public static void main(String[] args) throws Exception {
Pattern p = Pattern.compile("\\berror\\b", Pattern.CASE_INSENSITIVE);
int count = 0;
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("log.txt"), "UTF-8"))) {
String s;
while ((s = br.readLine()) != null) {
if (p.matcher(s).find()) count++;
}
}
System.out.println("Строк с 'error': " + count);
}
}
(примерный вывод) Строк с 'error': 12
Пример 2 - использование BufferedReader.lines() для параллельной обработки:
import java.nio.file.*;
import java.util.stream.*;
public class Adv2 {
public static void main(String[] args) throws Exception {
try (Stream lines = Files.lines(Paths.get("big.txt"))) {
long matches = lines.parallel()
.filter(l -> l.contains("TODO"))
.count();
System.out.println(matches);
}
}
}
(вывод: количество строк с TODO)
Пример 3 - LineNumberReader для нумерации строк при разборе ошибок:
import java.io.*;
public class Adv3 {
public static void main(String[] args) throws Exception {
try (LineNumberReader lnr = new LineNumberReader(new FileReader("script.txt"))) {
String s;
while ((s = lnr.readLine()) != null) {
if (s.contains("error")) {
System.out.println("Ошибка в строке " + lnr.getLineNumber() + ": " + s);
}
}
}
}
}
(примерный вывод) Ошибка в строке 42: // error: unexpected token
Пример 4 - чтение из сокета построчно (серверная сторона):
import java.net.*;
import java.io.*;
public class Adv4 {
public static void main(String[] args) throws Exception {
try (ServerSocket ss = new ServerSocket(12345)) {
Socket s = ss.accept();
try (BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println("Client: " + line);
}
}
}
}
}
(при подключении клиента и отправке строк) Client: hello Client: status=ok
Пример 5 - чтение больших файлов без загрузки в память с контролем буфера:
import java.io.*;
public class Adv5 {
public static void main(String[] args) throws Exception {
try (BufferedReader br = new BufferedReader(new FileReader("huge.txt"), 16 * 1024)) {
String l;
while ((l = br.readLine()) != null) {
// обработка по одной строке
}
}
}
}
(эффективная обработка больших файлов без OOM)
Пояснения: примеры демонстрируют разные сценарии: подсчёт совпадений с помощью регулярных выражений, ленивую и параллельную обработку потоков, получение номеров строк, работу по сети и оптимизацию буфера.