ReadLine: примеры (JAVA)

Руководство по readLine в Java
Раздел: Ввод-вывод (I/O) с буферизацией
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. При достижении EOF readLine() возвращает 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 ...
  • Не закрытие ресурсов. Отсутствие try-with-resources может привести к утечкам файловых дескрипторов.
  • Использование DataInputStream.readLine - потеря корректной обработки кодировок; метод помечен как deprecated.
  • Ожидание взаимодействия в окружении без консоли. System.console() может вернуть null в IDE или при перенаправленном вводе.
  • Смешивание Scanner.nextInt() и nextLine() без очистки конца строки, что приводит к чтению пустой строки:
  • Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    String rest = sc.nextLine(); // прочитает остаток строки после числа
    (ввод: 5\nHello\n)
    rest будет пустой строкой, а не "Hello"
  • Проблемы с кодировкой при использовании StreamReader/FileReader без указания charset, что приводит к некорректным символам.

Изменения и статус в современных версиях Java

  • BufferedReader.readLine() сохраняет прежнюю сигнатуру и семантику; существенных изменений в API метода в последних версиях Java не происходило.
  • DataInputStream.readLine() давно помечен как deprecated и не рекомендуется к применению из-за проблем с кодировками.
  • В Java 8 добавлены потоки для построчной обработки: BufferedReader.lines() и Files.lines(), что предоставляет более гибкие и декларативные способы работы с построчным вводом.
  • Console по-прежнему зависит от окружения; в модульных и контейнерных сценариях доступ к консоли может быть ограничен.

Расширенные и редко встречающиеся примеры

Пример 1 - чтение файла с явной кодировкой и подсчёт строк, содержащих шаблон:

Пример java
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() для параллельной обработки:

Пример java
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 для нумерации строк при разборе ошибок:

Пример java
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 - чтение из сокета построчно (серверная сторона):

Пример java
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 - чтение больших файлов без загрузки в память с контролем буфера:

Пример java
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)

Пояснения: примеры демонстрируют разные сценарии: подсчёт совпадений с помощью регулярных выражений, ленивую и параллельную обработку потоков, получение номеров строк, работу по сети и оптимизацию буфера.

джава readLine function comments

En
ReadLine Reads a line of text