В чем разница между Java IO и Java NIO?

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

Ответ

Java IO (java.io) — это потоко-ориентированный, блокирующий API для ввода-вывода. Java NIO (java.nio, "New I/O") — это буфер-ориентированный, неблокирующий (или селекторный) API.

Основные различия:

Аспект Java IO Java NIO
Парадигма Потоковая (Stream-oriented) Буферная (Buffer-oriented) и канальная (Channel-oriented)
Блокировка Блокирующий I/O. Поток "засыпает", пока данные читаются/пишутся. Поддерживает неблокирующий режим. Поток может делать другую работу, если данные не готовы.
Основные абстракции Потоки (InputStream, OutputStream, Reader, Writer). Буферы (Buffer), Каналы (Channel), Селекторы (Selector).
Производительность Может быть менее эффективной при множестве соединений. Эффективнее для управления тысячами одновременных соединений (через Selector).

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

// Java IO (блокирующий, потоковый)
try (FileInputStream fis = new FileInputStream("file.txt")) {
    int byteData;
    while ((byteData = fis.read()) != -1) { // read() блокирует поток
        System.out.print((char) byteData);
    }
}

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

Когда что использовать:

  • Java IO — для простых, последовательных операций с файлами или сетевыми соединениями.
  • Java NIO — для высоконагруженных серверных приложений, требующих асинхронной обработки множества соединений (например, чат-серверы).