Что такое буфер (Buffer) в терминах NIO?
- Чем NIO отличается от обычного ввода-вывода?
- Зачем у буфера метод flip()?
- Что такое Channel и Selector?
Buffer — область памяти фиксированного размера, через которую данные читаются из канала и пишутся в него.
- У буфера есть position, limit и capacity; между записью и чтением —
flip() - Забытый flip — самая частая ошибка: читается пустота
А ещё NIO даёт каналы, буферы и Selector — один поток обслуживает много соединений
Подробно
Классический ввод-вывод (java.io) — потоки, которые передают данные по одному байту или массиву. NIO (java.nio) работает иначе: данные проходят через буфер, которым управляет приложение, а источником или приёмником служит канал (FileChannel, SocketChannel).
У буфера три показателя:
capacity— размер;position— где сейчас читаем или пишем;limit— граница доступных данных.
Канал записывает данные в буфер, двигая position. Чтобы прочитать записанное, вызывают flip(): limit становится текущей позицией, а position — нулём. После чтения — clear() или compact(), чтобы снова писать. Забытый flip() — самая частая ошибка: читать оказывается нечего.
Возможности NIO:
- неблокирующие каналы и Selector — один поток следит за многими сокетами и обрабатывает те, что готовы. На этом построены Netty и другие сетевые серверы;
- прямые буферы (
allocateDirect) — память вне кучи, меньше копирований при работе с ОС; - отображение файла в память (
MappedByteBuffer).
Для повседневной работы с файлами удобнее java.nio.file.Files.
Пример
try (FileChannel ch = FileChannel.open(Path.of("data.bin"))) {
ByteBuffer buf = ByteBuffer.allocate(4096);
while (ch.read(buf) != -1) {
buf.flip(); // переключить на чтение
while (buf.hasRemaining()) process(buf.get());
buf.clear(); // снова на запись
}
}Что хотят услышать
- Буфер как посредник между приложением и каналом.
- position, limit, capacity и flip.
- Что даёт NIO: Selector, неблокирующий ввод-вывод — плюс.
Частые ошибки
- Забыть переключить буфер между записью и чтением.
- Считать, что очистка буфера стирает его содержимое.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Очередь задач ввода-вывода, ожидающих выполнения в селекторе
- ✓Область памяти, через которую идёт обмен с каналом
- ✗Файл на диске, куда сохраняются промежуточные данные
- ✗Отдельный поток, обслуживающий операции чтения
Что спросят дальше
- Что означают позиция, лимит и ёмкость буфера?
- Чем канал отличается от классического потока?
Разбор темы
- NIO: каналы, буферы и неблокирующий ввод-вывод
io против nio, Channel и ByteBuffer с его flip/clear, Selector и event loop, влияние виртуальных потоков и NIO.2.
Связанные вопросы
- Зачем нужны direct-буферы (ByteBuffer.allocateDirect) и в чём их минусы? Senior
- Чем IO отличается от NIO? Middle
- Как виртуальные потоки изменили типичный выбор между блокирующим IO и неблокирующей моделью на Selector? Middle
- Что означают позиция, лимит и ёмкость у ByteBuffer, и что делает flip()? Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.