BufferedReader.readLine: примеры (JAVA)

Подробный разбор метода readLine в BufferedReader
Раздел: Потоки ввода-вывода (Streams) символьные
BufferedReader.readLine: String

Описание BufferedReader.readLine

Метод BufferedReader.readLine() из пакета java.io читает одну строку текста из связанного потока символов. Под строкой понимается последовательность символов, завершающаяся одним из символов конца строки: LF ('\n'), CR ('\r') или последовательностью CR+LF. Возвращаемая строка не содержит символы окончания строки.

Сигнатура: public String readLine() throws IOException.

Аргументы: метод не принимает параметров.

Возвращаемые значения и поведение:

  • Возвращает String с символами прочитанной строки, за исключением символов конца строки.
  • Если в потоке достигнут конец (EOF) и данных для формирования строки нет, возвращает null.
  • Если конец потока достигнут после чтения части строки (без завершающего символа конца строки), возвращает полученную строку.
  • При возникновении ошибок ввода-вывода выбрасывает IOException.

Особенности:

  • Метод блокирующий: при отсутствии данных исполнение ожидает появления символов или EOF.
  • Разделители строк убираются из возвращаемой строки.
  • Поведение зависит от кодировки, заданной в оборачивающем Reader (например, InputStreamReader).
  • Не обеспечивает ограничений по длине строки кроме доступной памяти.

Примеры использования readLine

Ниже приведены простые примеры чтения строк из разных источников. Каждый пример содержит код и результат.

Чтение из строки (StringReader)

import java.io.*;

public class Example1 {
    public static void main(String[] args) throws Exception {
        String data = "Первая строка\r\nВторая строка\nТретья";
        try (BufferedReader br = new BufferedReader(new StringReader(data))) {
            String s;
            while ((s = br.readLine()) != null) {
                System.out.println(s);
            }
        }
    }
}
Первая строка
Вторая строка
Третья

Чтение первой строки файла (FileReader, UTF-8)

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Example2 {
    public static void main(String[] args) throws Exception {
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(new FileInputStream("example.txt"), StandardCharsets.UTF_8))) {
            String first = br.readLine();
            System.out.println("Первая строка: " + first);
        }
    }
}
Первая строка: Содержимое файла (пример)

Чтение с System.in (ввод пользователем)

import java.io.*;

public class Example3 {
    public static void main(String[] args) throws Exception {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
            System.out.println("Введите строку:");
            String line = br.readLine();
            System.out.println("Вы ввели: " + line);
        }
    }
}
Введите строку:
(пользователь вводит) Привет
Вы ввели: Привет

Похожие средства в Java

В Java доступны другие способы чтения строк и потоков текста. Краткое описание и рекомендации:

  • BufferedReader.lines() - возвращает Stream<String> (Java 8+). Удобно для функциональной обработки и параллельных операций. Предпочтительнее при необходимости применять стрим-операции.
  • Scanner.nextLine() - разбирает вход по токенам и поддерживает парсинг типов. Удобен для простых случаев ввода с фильтрацией, но медленнее и более тяжёл для высокой производительности.
  • Files.readAllLines(Path) - читает весь файл в список строк. Удобно, если файл небольшой и нужен полный доступ к строкам сразу; не подходит для больших файлов из-за потребления памяти.
  • Console.readLine() - работает с консолью и предоставляет более удобный ввод пароля (secure) через readPassword. Доступен не во всех окружениях (IDE может вернуть null).

Выбор зависит от объёма данных, требований к памяти и необходимости функциональной обработки.

Аналоги в других языках

Короткие сравнения и примеры чтения строки в популярных языках и их отличия от BufferedReader.readLine()

Python

# чтение строки из файла
with open('example.txt', 'r', encoding='utf-8') as f:
    line = f.readline()
    print(line.rstrip('\n'))
(вывод первой строки без символа конца строки)

Отличия: встроенные функции работают с указанием кодировки и возвращают символ конца строки если не удалять; итерация по файлу более идиоматична.

JavaScript (Node.js)

const fs = require('fs');
const data = fs.readFileSync('example.txt', 'utf8');
const lines = data.split(/\r?\n/);
console.log(lines[0]);
(первая строка файла)

Отличия: чтение блокирует поток при sync-методах; требуется ручное разбиение по разделителю.

PHP

$f = fopen('example.txt', 'r');
$line = fgets($f);
echo rtrim($line, "\r\n");
fclose($f);
(первая строка файла)

C#

using System;
using System.IO;

class P {
  static void Main() {
    using (var r = new StreamReader("example.txt")) {
      string s = r.ReadLine();
      Console.WriteLine(s);
    }
  }
}
(первая строка файла)

Отличия: API очень схож с BufferedReader.readLine.

Go

package main

import (
  "bufio"
  "fmt"
  "os"
)

func main() {
  f, _ := os.Open("example.txt")
  defer f.Close()
  r := bufio.NewReader(f)
  line, _ := r.ReadString('\n')
  fmt.Print(line) // содержит '\n'
}
(первая строка с символом новой строки)

Отличия: в Go ReadString оставляет разделитель в строке; для удаления надо обрезать.

Kotlin

import java.io.BufferedReader
import java.io.FileReader

fun main() {
  BufferedReader(FileReader("example.txt")).use { br ->
    println(br.readLine())
  }
}
(первая строка файла)

Во многих языках концепция чтения строки схожа, но детали обработки конца строки и кодировок различаются.

Типичные ошибки и их проявления

  • Игнорирование null. При достижении EOF метод возвращает null, и попытка вызвать методы строки без проверки приводит к NullPointerException.
  • Неправильная кодировка. Если InputStreamReader создан без указания кодировки, используется системная кодировка, что может привести к искажённым символам (mojibake).
  • Чтение из уже закрытого потока приводит к IOException с сообщением о закрытом ресурсе.
  • Смешивание readLine() с побайтовыми чтениями без корректной согласованности привода потока может дать некорректный результат.

Пример: не проверяется null

import java.io.*;

public class Err1 {
    public static void main(String[] args) throws Exception {
        try (BufferedReader br = new BufferedReader(new StringReader(""))) {
            String s = br.readLine();
            System.out.println(s.length()); // NPE, так как s == null
        }
    }
}
Exception in thread "main" java.lang.NullPointerException
    at Err1.main(Err1.java:8)

Пример: чтение после закрытия

import java.io.*;

public class Err2 {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new StringReader("abc\n"));
        br.close();
        br.readLine();
    }
}
Exception in thread "main" java.io.IOException: Stream closed
    at java.io.StringReader.checkOpen(StringReader.java:64)
    at java.io.StringReader.read(StringReader.java:108)
    ...

Пример: неправильная кодировка (символы искажены)

import java.io.*;
import java.nio.charset.Charset;

public class Err3 {
    public static void main(String[] args) throws Exception {
        byte[] bytes = "Привет".getBytes("UTF-8");
        try (BufferedReader br = new BufferedReader(new InputStreamReader(
                new ByteArrayInputStream(bytes), Charset.forName("Windows-1251")))) {
            System.out.println(br.readLine());
        }
    }
}
Привет

Изменения и история

Метод BufferedReader.readLine() сохраняет стабильный контракт в ранних и современных версиях Java. Ключевые моменты в истории:

  • Сам метод не претерпел значимых изменений API в недавних релизах.
  • В Java 8 добавлен метод lines() у BufferedReader, возвращающий Stream<String> для удобной функциональной обработки.
  • Устаревший метод DataInputStream.readLine() был помечен как небезопасный/нежелательный; для чтения строк рекомендуется использовать BufferedReader с указанием кодировки.

Расширенные и нестандартные примеры

Подробные сценарии использования с пояснениями.

Чтение HTTP-заголовков из сокета до пустой строки

Пример java
import java.io.*;
import java.net.*;

public class Adv1 {
    public static void main(String[] args) throws Exception {
        try (Socket s = new Socket("example.com", 80);
             BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
             BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()))) {

            bw.write("GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n");
            bw.flush();

            String line;
            while ((line = br.readLine()) != null && !line.isEmpty()) {
                System.out.println(line);
            }
        }
    }
}
(вывод строк заголовков HTTP до пустой строки)

Чтение GZIP-содержимого и разбор строк

Пример java
import java.io.*;
import java.util.zip.GZIPInputStream;

public class Adv2 {
    public static void main(String[] args) throws Exception {
        try (FileInputStream fis = new FileInputStream("data.txt.gz");
             GZIPInputStream gis = new GZIPInputStream(fis);
             BufferedReader br = new BufferedReader(new InputStreamReader(gis, "UTF-8"))) {

            String s;
            while ((s = br.readLine()) != null) {
                // обработка строки
                System.out.println(s);
            }
        }
    }
}
(строки распакованного файла)

Реализация чтения по нестандартному разделителю

Пример java
import java.io.*;

public class Adv3 {
    // пример: читать до символа ';' вместо '\n'
    public static String readUntilSemicolon(BufferedReader br) throws IOException {
        StringBuilder sb = new StringBuilder();
        int ch;
        while ((ch = br.read()) != -1) {
            if (ch == ';') break;
            sb.append((char) ch);
        }
        if (sb.length() == 0 && ch == -1) return null; // EOF
        return sb.toString();
    }

    public static void main(String[] args) throws Exception {
        String data = "one;two;three;";
        try (BufferedReader br = new BufferedReader(new StringReader(data))) {
            String p;
            while ((p = readUntilSemicolon(br)) != null) {
                System.out.println(p);
            }
        }
    }
}
one
two
three

Параллельная обработка большого файла с Stream API

Пример java
import java.io.*;
import java.nio.file.*;
import java.util.stream.*;

public class Adv4 {
    public static void main(String[] args) throws Exception {
        try (BufferedReader br = Files.newBufferedReader(Paths.get("big.txt"))) {
            // использовать stream для фильтрации и параллельной обработки
            br.lines()
              .parallel()
              .filter(s -> s.contains("ERROR"))
              .forEach(System.out::println);
        }
    }
}
(вывод строк, содержащих ERROR, порядок может быть непредсказуем)

Чтение больших строк без переполнения буфера

BufferedReader использует внутренний буфер, но при очень длинных строке строка собирается динамически в памяти (StringBuilder). Для управления памятью можно читать порциями через read(char[]), но для логики «строка по строке» стандартный readLine остаётся удобным.

джава BufferedReader.readLine function comments

En
BufferedReader.readLine Reads a line of text