IO и NIO
Тема дорожной карты · Java
Java I/O и NIO вместе охватывают полный спектр операций ввода-вывода, доступных на JVM, — от простого чтения файлов с BufferedReader до высокопроизводительных неблокирующих сетевых серверов, построенных с Selector и SocketChannel. Оригинальный пакет java.io предоставляет блокирующий потоковый I/O: InputStream/OutputStream для байтов и Reader/Writer для символов, с декораторными классами BufferedInputStream, DataInputStream и GZIPInputStream, добавляющими возможности через компоновку. Java NIO (java.nio), введённый в Java 1.4, переключает модель на буферы и каналы: данные читаются в ByteBuffer из ReadableByteChannel, а класс Selector позволяет одному потоку мультиплексировать I/O-события (readable, writable, connectable) на тысячах экземпляров SelectableChannel одновременно — основа фреймворков вроде Netty. NIO.2 (java.nio.file), добавленный в Java 7, предоставляет API Path, утилитный класс Files, WatchService для уведомлений об изменениях файловой системы и AsynchronousFileChannel для по-настоящему асинхронного I/O через Future или CompletionHandler. Понимание Java I/O и NIO критически важно при работе с высокопроизводительными Java-приложениями: выбор между блокирующим java.io для простоты, буферами и каналами NIO для пропускной способности и Files из NIO.2 для удобства зависит от конкретных требований к задержке, пропускной способности и конкурентности вашей системы.
Как это работает
IO и NIO имеет java.io (legacy блокирующие потоки: InputStream, OutputStream, Reader, Writer) и java.nio (современные channels + buffers, non-blocking, Path API). Для file I/O предпочитайте NIO Path API (Files.readString(path), Files.write(path, content), Files.lines(path).forEach(...)). Для сетевых сокетов NIO Channels + Selectors дают non-blocking I/O на масштабе. Async file I/O — через AsynchronousFileChannel. HTTP-клиент (java.net.http.HttpClient, с 11) reactive-aware.
Когда применять
Для файлов — всегда Files.*-методы: лаконично, современно, по дефолту UTF-8. Для HTTP — java.net.http.HttpClient лучше Apache HttpClient или legacy HttpURLConnection. Для сетевых серверов фреймворки (Netty, Vert.x) абстрагируют NIO. Reader/Writer — для текста, InputStream/OutputStream — для бинаря; всегда указывайте charset (StandardCharsets.UTF_8).
Типичные ошибки
Ловушки IO и NIO: не закрытые streams (ресурсная утечка — try-with-resources); platform-default charset (Windows тихо cp1252); чтение огромных файлов через readAllBytes (OOM — стримите); блокирующий I/O на main-thread однопоточного app-сервера (UI замораживается / latency запросов растёт).