You are already somewhat familiar with Java I/O through the use of the System.out object, which youâve used to display text on the console. In early Java versions, I/O was handled through the java.io package using classes such as InputStream, OutputStream, Reader, and Writer. These âclassic streamsâ were foundational for reading and writing files, handling console input, or communicating over network sockets. For example, a file could be read using a FileInputStream and written using a FileOutputStream:
try (FileInputStream in = new FileInputStream("input.txt");
     FileOutputStream out = new FileOutputStream("output.txt")) {
    int data;
    while ((data = in.read()) != -1) {
        out.write(data);
    }
}
While functional, the original stream-based model of Java 1.1 was blocking, inflexible, and inefficient for high-performance or large-scale applications. Modern systems demand asynchronous, non-blocking, and scalable I/O operations â requirements that led to the introduction of the New I/O (NIO) framework.
Introduced in Java SE 1.4, the java.nio package represented a paradigm shift from traditional stream I/O. Instead of handling one byte or character at a time, NIO operates on buffers and channels, allowing developers to transfer data efficiently between memory and I/O devices. 
Channels such as FileChannel and SocketChannel can read and write asynchronously, while ByteBuffer objects store data in memory for quick manipulation. This design allows for scalable, high-performance servers and applications capable of managing thousands of concurrent connections without spawning thousands of threads.
NIO also introduced Selectors, which monitor multiple channels for events (read/write/connect) in a single thread, significantly improving efficiency for network-based applications. The framework brought Java closer to modern systems programming techniques, similar to epoll or kqueue mechanisms in Unix-like systems.
JSR 203, also known as NIO.2, was a major enhancement to Javaâs I/O APIs, standardized in Java SE 7. It introduced a new file I/O system under the java.nio.file package, with the centerpiece being the Path and Files classes. These provide a modern, object-oriented alternative to java.io.File and offer better error handling, symbolic link support, and access to advanced filesystem operations such as atomic file moves and directory traversal.
NIO.2 also introduced the Asynchronous I/O (AIO) API, enabling operations that donât block threads while waiting for file or socket I/O to complete. Classes such as AsynchronousFileChannel and AsynchronousSocketChannel provide scalable concurrency without requiring thread pools of matching size. In modern Java (SE 22 and beyond), NIO.2 remains the backbone of both synchronous and asynchronous I/O, forming the foundation for frameworks like Netty, Vert.x, and even Javaâs own HttpClient.
After completing this module, you will be able to:
Files and Path APIs for modern file manipulation.AsynchronousFileChannel and AsynchronousSocketChannel.