В чем разница пакетов java.io и java.nio
Что проверяют
Понимаете ли вы разные модели ввода-вывода, а не только названия пакетов. Следом обычно спрашивают, как работает Selector, или что меняют виртуальные потоки в выборе между блокирующим и неблокирующим кодом.
Как отвечать
- java.io: JDK 1.0, потоковая модель.
InputStream/OutputStreamдля байтов,Reader/Writerдля символов, возможности добавляются декораторами (BufferedInputStream). Операции блокирующие:read()держит поток, пока не придут данные; - java.nio: JDK 1.4, модель «каналы и буферы». Данные идут из
ChannelвByteBufferи обратно, у буфера естьposition,limit,capacity, между записью и чтением вызываетсяflip(). Сетевые каналы переводятся в неблокирующий режим черезconfigureBlocking(false)и регистрируются вSelector, так один поток обслуживает тысячи соединений. На этом построена Netty; - NIO.2 (
java.nio.file): JDK 7.PathиFilesвместоFile: исключения вместо молчаливогоfalse, атрибуты, симлинки,WatchService.
Назовите то, чего в io нет: FileChannel.map() для файлов, отображённых в память, transferTo() для копирования без лишнего прохода через память приложения, прямые буферы ByteBuffer.allocateDirect().
Важный нюанс: неблокирующим бывает только сетевой ввод-вывод, FileChannel всегда блокирующий. Сам по себе NIO код не ускоряет, выигрыш появляется на большом числе одновременных соединений. С JDK 21 виртуальные потоки вернули модель «поток на запрос» с блокирующими вызовами без прежней цены, поэтому селекторы руками в прикладном коде пишут редко.
Где спотыкаются
Повторяют, что io читает по байту, а nio блоками. BufferedInputStream и read(byte[]) тоже читают блоками, разница в модели, а не в размере порции.
Говорят, что nio всегда неблокирующий и всегда быстрее. Файловые каналы блокирующие, а на чтении одного файла разница часто в пределах погрешности.
Путаются в буфере: забывают flip() перед чтением и получают пустой результат, не отличают clear() от compact().