Что такое Java NIO и его основные отличия от стандартного I/O?

«Что такое Java NIO и его основные отличия от стандартного I/O?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Java NIO (New I/O) — это API для неблокирующего и буферизованного ввода-вывода, представленное в Java 1.4. Оно предназначено для эффективной работы с большим количеством соединений или данных.

Ключевые отличия от потокового I/O (java.io):

  • Буферизация: NIO работает с буферами (channels читают/пишут в Buffer), а I/O — с потоками байтов/символов.
  • Неблокирующий режим: Канал (Channel) может работать в неблокирующем режиме, позволяя потоку проверять доступность данных без ожидания.
  • Селекторы: Позволяют одному потоку управлять множеством каналов (мультиплексирование).

Основные компоненты:

  1. Buffers (ByteBuffer, CharBuffer) — контейнеры для данных.
  2. Channels (FileChannel, SocketChannel) — абстракции для двунаправленной передачи данных.
  3. Selectors — механизм для мониторинга нескольких каналов на готовность к операциям I/O.

Пример чтения файла с FileChannel и ByteBuffer:

import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;

try (FileChannel channel = FileChannel.open(Paths.get("file.txt"))) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (channel.read(buffer) > 0) {
        buffer.flip(); // Переключаем буфер на чтение
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        buffer.clear(); // Очищаем буфер для следующего чтения
    }
}

Почему это эффективно? NIO минимизирует дорогостоящие системные вызовы за счет работы с буферами и позволяет создавать масштабируемые сетевые серверы, обрабатывающие тысячи соединений в небольшом числе потоков.