В чём заключается разница между IO и NIO?
Java IO (Input/Output) и Java NIO (New I/O, также расшифровывается как Non-blocking I/O) представляют два подхода к операциям ввода/вывода, различающихся по ориентации на данные, модели блокировки и масштабируемости.
Аналогия из жизни: IO — это чтение книги строго по порядку, страница за страницей, без возможности вернуться назад. NIO — это работа с блокнотом, где можно в любой момент перелистнуть на нужную страницу, делать закладки и обрабатывать несколько блокнотов одновременно.
Потокоориентированность vs буфер-ориентированность
Java IO является потокоориентированным: данные читаются или записываются последовательно, байт за байтом (или символ за символом). Прочитанные данные нигде не кэшируются, и вернуться назад по потоку нельзя. Java NIO работает с буферами: данные сначала считываются в буфер (ByteBuffer), а затем обрабатываются. Это даёт гибкость — можно перемещаться по буферу вперёд и назад, перечитывать данные.
Блокирующий vs неблокирующий режим
Потоки IO являются блокирующими: вызов read() или write() блокирует поток выполнения до завершения операции. В NIO каналы могут работать в неблокирующем режиме: поток выполнения запрашивает данные и получает то, что доступно на данный момент (или ничего), и может продолжать другую работу.
Селекторы
В NIO существуют селекторы (Selector), позволяющие одному потоку выполнения мониторить несколько каналов ввода/вывода. Это ключевое преимущество для сетевых приложений, обслуживающих тысячи соединений.
| Характеристика | IO | NIO |
|---|---|---|
| Ориентация | Потоки (stream) | Буферы (buffer) |
| Блокировка | Блокирующий | Неблокирующий (опционально) |
| Модель | Один поток на соединение | Один поток на множество каналов |
| Обратное перемещение | Невозможно | Возможно (в буфере) |
| Основные классы | InputStream, OutputStream | Channel, Buffer, Selector |
Когда что использовать
- IO подходит для простых задач: чтение конфигурации, запись логов, обработка небольших файлов.
- NIO подходит для высоконагруженных сетевых приложений и работы с большими файлами, где важна эффективность и масштабируемость.
На собеседовании: ключевые отличия — потоковая vs буферная модель, блокирующий vs неблокирующий режим, и наличие селекторов в NIO. Частая ошибка — говорить, что NIO всегда лучше IO. На практике для простого файлового ввода/вывода IO (или NIO.2 Files API) проще и достаточен.