JavaRush /Курсы /JAVA 25 SELF /Основы java.io и java.nio: отличие, эволюция API

Основы java.io и java.nio: отличие, эволюция API

JAVA 25 SELF
35 уровень, 0 лекция
Открыта

1. Как Java научилась работать с файлами

Java и файлы: с чего всё начиналось

Когда-то, в далёком 1996 году, разработчики языка предложили первый способ работы с файлами — пакет java.io. В нём появились такие классы, как File, FileInputStream, FileOutputStream, Reader, Writer и другие. Эти классы позволяли проводить разные манипуляции с файлами: узнавать, существует ли файл, его размер, дату изменения, и работать с директориями.

Но, как часто бывает с первыми версиями, всё было не идеально — многие вещи можно было сделать удобнее и безопаснее.

Ограничения старого API (java.io)

  • File — не файл, а «ярлык». Класс File не умеет читать или записывать содержимое. Он описывает путь и метаданные. Для чтения/записи нужны отдельные потоки: FileInputStream/FileOutputStream или Reader/Writer.
  • Работа с путями — боль. Склеивание путей вручную вроде "C:\\Users\\" + user + "\\Documents" часто ломалось при переносе между Windows и Linux.
  • Нет поддержки символических ссылок. Старый API не понимал симлинки и мог работать с ними некорректно.
  • Слабая поддержка атрибутов. Сложно получить права доступа, владельца, флаги «скрытый» и т.п.
  • Неэффективность для больших файлов. Классические потоки не давали удобных и быстрых сценариев для больших объёмов данных, отсутствовал асинхронный ввод-вывод.

Появление java.nio.file (NIO.2, Java 7)

В Java 7 появился новый пакет: java.nio.file (часто — NIO.2). Он принёс:

  • Path — современная абстракция пути (включая пути внутри ZIP, облачных и сетевых файловых систем).
  • Files — статические утилиты для чтения, записи, копирования, удаления.
  • FileSystem — работа не только с локальным диском, но и с другими файловыми системами.
  • Поддержка символических ссылок, расширенных атрибутов, прав доступа.
  • Асинхронный ввод-вывод и улучшенная производительность для больших данных.
  • Удобная работа с директориями и потоковыми API.

NIO расшифровывается как «New Input/Output», и хотя ему уже больше десяти лет, для Java это всё равно современный стандарт.

2. Сравнение подходов: java.io vs java.nio.file

Класс File (java.io)

  • Представляет путь к файлу или директории и их метаданные.
  • Не умеет читать/писать содержимое файла.
  • Позволяет узнать существование, размер, тип (файл/директория), абсолютный путь и т.п.
import java.io.File;

public class ExampleIO {
    public static void main(String[] args) {
        File file = new File("example.txt");
        if (file.exists()) {
            System.out.println("Файл существует!");
            System.out.println("Размер: " + file.length() + " байт");
        }
    }
}

Класс Path (java.nio.file)

  • Современная абстракция пути, умеет натурально комбинироваться и нормализоваться.
  • Может представлять локальные, архивные и сетевые пути.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ExampleNIOPath {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("example.txt");
        if (Files.exists(path)) {
            System.out.println("Файл найден!");
            System.out.println("Размер: " + Files.size(path) + " байт");
        }
    }
}

Класс Files (java.nio.file)

  • Набор статических методов для чтения/записи целиком и по частям.
  • Копирование, удаление, перемещение файлов.
  • Создание/удаление директорий.
  • Доступ к расширенным атрибутам.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class ExampleNIOFiles {
    public static void main(String[] args) throws Exception {
        Path path = Paths.get("example.txt");
        List<String> lines = Files.readAllLines(path);
        for (String line : lines) {
            System.out.println(line);
        }
    }
}

Таблица сравнения

Функция
java.io.File
java.nio.file.Path + Files
Представление пути Да Да
Чтение/запись содержимого Нет Да (через Files)
Работа с путями Неудобно Удобно (resolve, normalize)
Символические ссылки Нет Да
Атрибуты файлов Ограничено Расширенно
Асинхронный IO Нет Да (NIO.2)
Кросс-платформенность Частичная Отличная

3. Когда использовать что?

Старый API (java.io): когда он нужен?

  • Для поддержки легаси-кода. Если проект начался до Java 7 и везде используются File, FileInputStream, FileOutputStream, возможно, придётся придерживаться совместимости.
  • В новых проектах — не рекомендуется. Использовать «старичка» File сегодня — всё равно что смотреть видео с VHS-кассет.

Новый API (java.nio.file): современный стандарт

  • Всегда предпочитайте Path и Files в новых проектах.
  • Проще, безопаснее, мощнее и лучше интегрируется со стримами, лямбдами и try-with-resources.

Краткая памятка

  • Чтение, запись, копирование, удаление? — через Files.
  • Работа с путями (объединение, нормализация)? — через Path.
  • Размер, дата, права доступа? — Files.getAttribute() и сопутствующие методы.
  • Обход директорий, рекурсивно? — Files.walk, Files.list.

4. Примеры: как выглядел бы код на старом и новом API

Пример 1: Проверка существования файла

Старый способ:

import java.io.File;

File file = new File("data.txt");
if (file.exists()) {
    System.out.println("Файл найден!");
}

Новый способ:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("data.txt");
if (Files.exists(path)) {
    System.out.println("Файл найден!");
}

Пример 2: Чтение всех строк файла

Старый способ:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

File file = new File("data.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}
reader.close();

Новый способ:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

Path path = Paths.get("data.txt");
List<String> lines = Files.readAllLines(path);
for (String line : lines) {
    System.out.println(line);
}

Комментарий: Новый способ короче и безопаснее; с try-with-resources управление ресурсами ещё проще.

Пример 3: Запись строки в файл

Старый способ:

import java.io.FileWriter;

FileWriter writer = new FileWriter("output.txt");
writer.write("Привет, файл!");
writer.close();

Новый способ:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("output.txt");
Files.write(path, "Привет, файл!".getBytes());

5. Полезные нюансы

Почему Java решила всё переделать?

  • Безопасность и надёжность. Меньше ошибок с закрытием ресурсов и путями.
  • Кросс-платформенность. Единые классы для Windows, Linux и даже архивов ZIP.
  • Лёгкость расширения. Проще добавлять поддержку облачных и сетевых ФС.
  • Производительность. Лучшее поведение на больших файлах и асинхронные операции.
  • Совместимость с современным Java-стеком. Лямбды, стримы, try-with-resources.

Как перейти со старого API на новый?

Почти всегда можно преобразовать File в Path и обратно:

File file = new File("data.txt");
Path path = file.toPath();
File file2 = path.toFile();

Что делать, если встретили старый код?

  • Не пугайтесь: всё можно сделать проще и современнее.
  • Есть возможность — переписывайте на java.nio.file.
  • Нет возможности — используйте мосты (toPath(), toFile()) и мигрируйте постепенно.

6. Заключительный пример: мини-приложение

Пример: Проверяем, существует ли файл, и выводим его размер.

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FileInfo {
    public static void main(String[] args) {
        Path path = Paths.get("test.txt");
        if (Files.exists(path)) {
            try {
                long size = Files.size(path);
                System.out.println("Файл найден. Размер: " + size + " байт");
            } catch (Exception e) {
                System.out.println("Ошибка при получении размера файла: " + e.getMessage());
            }
        } else {
            System.out.println("Файл не найден!");
        }
    }
}

Что мы здесь использовали:

  • Path — представление пути.
  • Files.exists() — проверка существования.
  • Files.size() — получение размера.

7. Типичные ошибки при работе с файловыми API

Ошибка №1: Ожидание, что File может читать или писать содержимое. На самом деле File — это только «ярлык». Для чтения/записи используйте FileInputStream/FileOutputStream (старый API) или утилиты Files (новый API).

Ошибка №2: Ручное склеивание путей через + или слеш. Это приводит к ошибкам на разных ОС. Используйте Path.resolve() или Paths.get(...) с несколькими аргументами.

Ошибка №3: Забыли закрыть поток. В старом API это частая причина утечек ресурсов. В новом API многие операции через Files потоков не создают, а где они нужны — применяйте try-with-resources.

Ошибка №4: Использование старого API в новых проектах. Если стартуете новый проект — выбирайте java.nio.file. К java.io имеет смысл обращаться лишь для совместимости с легаси-кодом.

1
Задача
JAVA 25 SELF, 35 уровень, 0 лекция
Недоступна
Где мой тайный дневник? 🕵️‍♀️
Где мой тайный дневник? 🕵️‍♀️
1
Задача
JAVA 25 SELF, 35 уровень, 0 лекция
Недоступна
Сколько весит ваше игровое сохранение? 💾
Сколько весит ваше игровое сохранение? 💾
Комментарии (11)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Victor Уровень 50
30 августа 2026
30.08.2026
Anna Klushkina Уровень 2
19 августа 2026
35⛏️
Victor Уровень 50
30 августа 2026
Сейчас 30.08.2026 у тебя уровень 66, 19.08.2026 у тебя был уровень 35. Поделись секретом - как пройти 31 уровень за 11 дней? plz
rwnmei Уровень 57
2 сентября 2026
терминаторы сидят просто
Anna Klushkina Уровень 2
6 сентября 2026
Да я просто лекции вперед открыла за материю с задач, на самом деле я на 43 уровне сейчас
Anna Klushkina Уровень 2
8 октября 2026
Update неделю назад закончила курс. Дальше с ИИ составила список "вопрос - развернутый ответ" по всей теории, его учу, и решаю задачи на повторение. А обычный курс по java 8 так и не закончила, не знаю понадобится ли.
Gans Electro Уровень 59
27 октября 2026
Задачи в старом курсе до 20 уровня просто шедевр, нет ничего лучше. Задачи с 25+ уровня хоть и старые или немного упрямые но тоже интересные. Они написаны людьми и лучше на сайте уже не будет. Те задачи дают тот "кайф от решенной задачи"
SB Уровень 115
22 июля 2026
35!
Kazbekov Andrew Уровень 66
16 июля 2026
Наполнение лекции достойное, но количество задач и отсутствие проработки нового api в задачах являются существенным минусом
Максим Li Уровень 51
4 апреля 2026
35 - 4.04.2026
Andrey Уровень 6
28 сентября 2025
35