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

Ответ

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 — для высоконагруженных серверных приложений, требующих асинхронной обработки множества соединений (например, чат-серверы).

Ответ 18+ 🔞

Слушай, а вот эта вся история с Java IO и NIO — это ж, блядь, как два разных мира, в рот меня чих-пых! Один — старый, спокойный дедок, а второй — шустрый пацан с прикрученным селектором.

Короче, смотри. Java IO (этот старый java.io) — он работает как садовый шланг. Потоковая хуйня, понимаешь? Ты открыл кран — вода течёт, и ты стоишь и ждёшь, пока ведро наполнится, нихуя другого делать не можешь. Это и есть блокирующий режим. Поток уснул, пока операция не завершится. Просто, предсказуемо, но если соединений дохуя — всё встанет колом.

А вот Java NIO (этот java.nio, "новый") — он уже не шланг, а, блядь, система умных резервуаров и краников. Буферно-канальная тема. Данные не просто льются, а складываются в буфер (Buffer), как в тачку. И главный пиздец — он умеет в неблокирующий режим. Ты можешь каналу (Channel) сказать: "Чувак, есть данные?" — а он тебе: "Нет, пошёл нахуй, не готово". И твой поток не спит, а идёт делать другие дела! А когда всё готово, забираешь данные из буфера. Для управления кучей таких каналов есть ещё селектор (Selector) — этакий диспетчер, который орет, когда какой-то из каналов проснулся и готов к работе.

Краткая сводка, чтобы не еб... сломать мозг:

Чё да как Java IO (Старина) Java NIO (Шустрик)
Как работает Поток, ручеёк (Stream). Буфер и канал (Buffer & Channel).
Блокировка Да, блокирует намертво. Ждёт. Может не блокировать. "Не готово? Ок, потом зайду".
Основные штуки InputStream, OutputStream. Buffer, Channel, Selector.
Для чего сгодится Простые задачи: файл прочитать, в сеть байты послать. Высоконагруженное говно: 10к клиентов на сервере одновременно.

Смотри, как они файл читают, совсем по-разному:

// Java IO - классика, блокировка, поток
try (FileInputStream fis = new FileInputStream("file.txt")) {
    int byteData;
    // read() тут уснёт, пока байт не прочитает
    while ((byteData = fis.read()) != -1) {
        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, когда пишешь какую-нибудь дичь вроде чат-сервера, где одновременно сидят овердохуища клиентов. Чтобы твой поток не уснул на каждом из них, а селектор за всеми присматривал. Это для производительности, ёпта!

Вот и вся магия. IO — как поезд на одном рельсе, едет и всё. NIO — как развязка с десятком съездов, светофорами и диспетчерской. Выбирай по обстановке, а то так и до deadlock'а недалеко, блядь.