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

Примеры работы с FileReader в Java
Раздел: Потоки ввода-вывода (Streams) символьные
FileReader(File file, String fileName)

Общее описание и сигнатуры

Класс java.io.FileReader предназначен для чтения текстовых данных из файлов как поток символов. FileReader наследуется от InputStreamReader и использует системную кодировку по умолчанию для преобразования байтов в символы. Частое применение - простое посимвольное или по-блочно чтение текстовых файлов в кодировке по умолчанию.

Конструкторы

  • FileReader(String fileName) - открывает файл по имени; выбрасывает FileNotFoundException, если файл не найден.
  • FileReader(File file) - открывает файл по объекту java.io.File.
  • FileReader(FileDescriptor fd) - использует существующий файловый дескриптор.

Основные методы

  • int read() - читает один символ и возвращает его как целое значение (0..65535), при достижении конца возвращает -1.
  • int read(char[] cbuf) - пытается заполнить массив символов, возвращает число реально прочитанных символов или -1.
  • int read(char[] cbuf, int off, int len) - читает до len символов в cbuf, начиная с off, возвращает количество прочитанных символов или -1.
  • void close() - закрывает поток и освобождает ресурс; рекомендуется использовать try-with-resources.
  • При ошибках может выбрасываться IOException и дочерние (FileNotFoundException, UnsupportedEncodingException не напрямую от FileReader, но при работе с кодировками через InputStreamReader).

Особенности

  • FileReader использует кодировку по умолчанию платформы; это делает поведение зависимым от окружения и может привести к некорректной обработке файлов в известной кодировке. Для явного указания кодировки лучше применять InputStreamReader с явным Charset или java.nio.file.Files.newBufferedReader(Path, Charset).
  • FileReader - символьный поток; не подходит для бинарных данных.

Короткие примеры применения

1. Базовое чтение символов

import java.io.FileReader;
import java.io.IOException;

public class Example1 {
    public static void main(String[] args) throws IOException {
        try (FileReader fr = new FileReader("example.txt")) {
            int ch;
            while ((ch = fr.read()) != -1) {
                System.out.print((char) ch);
            }
        }
    }
}
(содержимое файла example.txt выводится посимвольно)
Пример текста
123

2. Чтение блоком в буфер

import java.io.FileReader;
import java.io.IOException;

public class Example2 {
    public static void main(String[] args) throws IOException {
        try (FileReader fr = new FileReader("example.txt")) {
            char[] buf = new char[32];
            int n;
            while ((n = fr.read(buf)) != -1) {
                System.out.print(new String(buf, 0, n));
            }
        }
    }
}
(тот же вывод, но читается блоками)
Пример текста
123

3. Чтение строк через BufferedReader

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Example3 {
    public static void main(String[] args) throws IOException {
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        }
    }
}
Пример текста
123

4. Обработка отсутствия файла

import java.io.FileReader;
import java.io.IOException;

public class Example4 {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("no_such_file.txt")) {
            // ...
        } catch (IOException e) {
            System.out.println("Ошибка: " + e.getClass().getSimpleName() + " - " + e.getMessage());
        }
    }
}
Ошибка: FileNotFoundException - no_such_file.txt (No such file or directory)

Альтернативы в Java и их особенности

  • BufferedReader
  • Часто комбинируется с FileReader для эффективного построчного чтения. Предпочтителен при работе со строками и при необходимости метода readLine().

  • InputStreamReader + FileInputStream
  • Позволяет явно указать кодировку: new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8). Предпочтительнее для портативности кодировок.

  • Files.newBufferedReader(Path, Charset)
  • Современный NIO API. Удобен для указания Charset и работы с Path.

  • Files.readAllLines / Files.readString
  • Читают весь файл целиком. Удобно для небольших файлов, но не для больших по памяти.

  • FileInputStream
  • Для побайтовой работы. Применяется при обработке бинарных данных.

  • Scanner
  • Удобен для разбора токенов и парсинга по разделителям, но медленнее и тяжелее для простого чтения строк.

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

PHP

// file_get_contents
$txt = file_get_contents('example.txt');
echo $txt;
Пример текста
123

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

JavaScript (Node.js)

const fs = require('fs');
const txt = fs.readFileSync('example.txt', 'utf8');
console.log(txt);
Пример текста
123

Отличие: в Node.js кодировка указывается явно (например, 'utf8').

Python

with open('example.txt', 'r', encoding='utf-8') as f:
    print(f.read())
Пример текста
123

Отличие: в Python рекомендуется всегда указывать encoding для предсказуемости.

C#

using System.IO;

var text = File.ReadAllText("example.txt");
Console.WriteLine(text);
Пример текста
123

Отличие: StreamReader позволяет указать Encoding; File.ReadAllText по умолчанию использует UTF-8 в современных версиях .NET, но поведение платформозависимо в старых релизах.

Go

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    b, _ := ioutil.ReadFile("example.txt")
    fmt.Print(string(b))
}
Пример текста
123

Отличие: Go работает с байтами и преобразование в строку предполагает UTF-8.

Kotlin

import java.io.File

fun main() {
    println(File("example.txt").readText())
}
Пример текста
123

Отличие: Kotlin использует JVM API, есть удобные расширения для чтения с указанием Charset.

Lua

local f = io.open('example.txt', 'r')
local s = f:read('*a')
f:close()
print(s)
Пример текста
123

Отличие: меньше встроенной поддержки кодировок; требуется внешняя обработка для Unicode.

Типичные ошибки при использовании

  • Файл не найден (FileNotFoundException)
  • new FileReader("missing.txt");
    java.io.FileNotFoundException: missing.txt (No such file or directory)
  • Неправильная кодировка
  • Ожидание UTF-8 при чтении файла в другой кодировке приводит к искажённым символам. FileReader не позволяет указать кодировку напрямую.

    // файл в UTF-8, но среда использует другую кодировку
    try (FileReader fr = new FileReader("utf8file.txt")) {
        int c = fr.read();
        // ...
    }
    
    вывод могут содержать кракозябры вместо ожидаемых кириллических букв
  • Не закрытый поток (ресурсная утечка)
  • FileReader fr = new FileReader("example.txt");
    fr.read();
    // fr.close() может не вызваться при исключении
    
    Плавающие дескрипторы файла, исчерпание ресурсов при большом числе открытых файлов
  • Неправильное использование read(char[])
  • read(buf) не гарантирует полного заполнения массива; нужно проверять возвращаемое значение.

    char[] buf = new char[100];
    int n = fr.read(buf);
    System.out.println(new String(buf)); // может содержать старые символы в конце
    
    Вывод может содержать мусор после n символов; правильнее new String(buf,0,n)

Изменения и современные рекомендации

Класс FileReader сам по себе в Java изменялся мало и остаётся простым символьным адаптером для файлов. Основные эволюционные изменения связаны с появлением NIO.2 (Java 7) и классов в java.nio.file.Files, которые предлагают более гибкую работу с Path и Charset. В современной практике рекомендуется:

  • Для явного указания кодировки использовать Files.newBufferedReader(Path, Charset) или new InputStreamReader(new FileInputStream(file), charset).
  • Для больших файлов применять потоковую обработку через BufferedReader.lines() или стримы NIO.

Непосредственно методы FileReader не были объявлены устаревшими и остаются доступными.

Продвинутые и редкие сценарии

1. Явное указание кодировки через InputStreamReader

Пример java
import java.io.*;
import java.nio.charset.StandardCharsets;

public class Adv1 {
    public static void main(String[] args) throws IOException {
        try (InputStreamReader isr = new InputStreamReader(new FileInputStream("example-utf8.txt"), StandardCharsets.UTF_8);
             BufferedReader br = new BufferedReader(isr)) {
            br.lines().forEach(System.out::println);
        }
    }
}
(строки файла корректно выводятся как UTF-8)
Текст в UTF-8

2. Построчная обработка большого файла с подсчетом вхождений

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

public class Adv2 {
    public static void main(String[] args) throws IOException {
        long count = 0;
        try (BufferedReader br = new BufferedReader(new FileReader("big.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                if (line.contains("ERROR")) count++;
            }
        }
        System.out.println("ERROR lines: " + count);
    }
}
ERROR lines: 42

3. Чтение части файла: смещение и длина

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

public class Adv3 {
    public static void main(String[] args) throws IOException {
        try (FileReader fr = new FileReader("example.txt")) {
            fr.skip(10); // перейти на 10 символов вперёд
            char[] buf = new char[20];
            int n = fr.read(buf, 0, buf.length);
            if (n > 0) System.out.println(new String(buf, 0, n));
        }
    }
}
(вывод 20 символов, начиная с позиции 11 файла)

4. Комбинация с CharsetDecoder для контроля декодирования

Пример java
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

public class Adv4 {
    public static void main(String[] args) throws IOException {
        CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
        try (FileInputStream fis = new FileInputStream("example.txt")) {
            byte[] b = new byte[64];
            int r;
            while ((r = fis.read(b)) != -1) {
                ByteBuffer bb = ByteBuffer.wrap(b, 0, r);
                CharBuffer cb = decoder.decode(bb);
                System.out.print(cb.toString());
            }
        }
    }
}
(правильное декодирование UTF-8 с контролем ошибок декодера)

5. Чтение ресурсов внутри JAR

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

public class Adv5 {
    public static void main(String[] args) throws IOException {
        try (InputStream is = Adv5.class.getResourceAsStream("/resource.txt")) {
            if (is == null) return;
            try (InputStreamReader isr = new InputStreamReader(is);
                 BufferedReader br = new BufferedReader(isr)) {
                br.lines().forEach(System.out::println);
            }
        }
    }
}
(содержимое resource.txt внутри JAR выводится корректно)

В расширенных сценариях часто комбинируются NIO и классы декодирования для повышения контроля над производительностью и обработкой кодировок. FileReader остаётся удобным для быстрых задач, но для критичного к кодировке и масштабируемого чтения предпочтительнее InputStreamReader, Files и NIO-подходы.

джава FileReader function comments

En
FileReader A reader for reading character files