Java输入输出:什么是NIO(New I/O)?

简介: Java NIO是一种高效I/O库,特征包括非阻塞性操作、通道(如文件、网络连接)、缓冲区和选择器。选择器监控通道状态变化,通知应用程序数据可读写,避免轮询,提升性能。示例代码展示了一个使用NIO的服务器,监听连接、读取数据并处理客户端通信。

NIO(New I/O)是Java中的一种新输入输出库,它提供了一种更高效的文件读写方式。相比于传统的IO库,NIO具有以下特点:

  1. 非阻塞性:NIO支持非阻塞I/O操作,这意味着在执行I/O操作时,程序不会被阻塞,而是可以继续执行其他任务。

  2. 通道(Channel):NIO中的通道(Channel)是一个抽象概念,它可以表示文件、网络连接等I/O资源。通过通道,可以实现数据的读写和传输。

  3. 缓冲区(Buffer):NIO使用缓冲区来存储数据,这样可以提高数据传输的效率。缓冲区可以是字节缓冲区(ByteBuffer)或字符缓冲区(CharBuffer)。

  4. 选择器(Selector):NIO中的选择器(Selector)用于监控多个通道的状态变化,当某个通道有数据可读或可写时,可以选择器会通知应用程序。这样可以避免轮询多个通道,提高程序的性能。

下面是一个简单的NIO示例代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class NIOExample {
   
    public static void main(String[] args) throws IOException {
   
        // 创建选择器
        Selector selector = Selector.open();

        // 打开服务器套接字通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress("localhost", 8080));

        // 注册到选择器,关注接受事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
   
            // 选择一组键,其相应的通道已为 I/O 操作准备就绪
            int readyChannels = selector.select();
            if (readyChannels == 0) continue;

            // 获取选择器选中的键集合
            Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
            while (keyIterator.hasNext()) {
   
                SelectionKey key = keyIterator.next();

                if (key.isAcceptable()) {
   
                    // 处理接受事件
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
   
                    // 处理读取事件
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int bytesRead = socketChannel.read(buffer);
                    if (bytesRead > 0) {
   
                        buffer.flip();
                        // 处理读取到的数据
                        while (buffer.hasRemaining()) {
   
                            System.out.print((char) buffer.get());
                        }
                        buffer.clear();
                    } else if (bytesRead < 0) {
   
                        // 客户端关闭连接
                        socketChannel.close();
                    }
                }

                // 移除已处理的键
                keyIterator.remove();
            }
        }
    }
}
目录
相关文章
|
2月前
|
Java
Java输入输出
Java输入输出
16 0
|
2月前
|
Java API
Java中文件与输入输出
Java中文件与输入输出
|
2月前
|
存储 Java 数据处理
|
2月前
|
存储 Java
Java输入输出
Java输入输出
|
2天前
|
Java
【JAVA基础篇教学】第十三篇:Java中I/O和文件操作
【JAVA基础篇教学】第十三篇:Java中I/O和文件操作
|
10天前
|
存储 Java
Java的`java.io`包包含多种输入输出类
Java的`java.io`包包含多种输入输出类。此示例展示如何使用`FileInputStream`从`input.txt`读取数据。首先创建`FileInputStream`对象,接着分配一个`byte`数组存储流中的数据。通过`read()`方法读取数据,然后将字节数组转换为字符串打印。最后关闭输入流释放资源。`InputStream`是抽象类,此处使用其子类`FileInputStream`。其他子类如`ByteArrayInputStream`、`ObjectInputStream`和`BufferedInputStream`各有特定用途。
20 1
|
18天前
|
缓存 Java API
Java NIO和IO之间的区别
NIO(New IO),这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
16 1
|
23天前
|
监控 Java 开发者
深入理解 Java 网络编程和 NIO
【4月更文挑战第19天】Java网络编程基于Socket,但NIO(非阻塞I/O)提升了效率和性能。NIO特点是非阻塞模式、选择器机制和缓冲区,适合高并发场景。使用NIO涉及通道、选择器和事件处理,优点是高并发、资源利用率和可扩展性,但复杂度、错误处理和性能调优是挑战。开发者应根据需求选择是否使用NIO,并深入理解其原理。
|
25天前
|
存储 监控 Java
浅谈Java NIO
浅谈Java NIO
7 0
|
26天前
|
消息中间件 存储 Java
【Java NIO】那NIO为什么速度快?
是这样的,在NIO零拷贝出现之前,一个I/O操作会将同一份数据进行多次拷贝。可以看下图,一次I/O操作对数据进行了四次复制,同时来伴随两次内核态和用户态的上下文切换,众所周知上下文切换是很耗费性能的操作。
29 1
【Java NIO】那NIO为什么速度快?