java nio api是一种用于处理i/o操作的先进api,它提供比传统阻塞i/o更好的性能和可伸缩性:缓冲区(buffers):在应用程序和操作系统之间传输数据的内存区域。通道(channels):抽象概念,表示应用程序和i/o设备之间的连接。选择器(selectors):用于轮询多个通道,以确定哪些通道已准备好读写。
Java I/O流中的NIO API:彻底解析
简介
NIO(非阻塞I/O)API是Java中用于处理I/O操作的更高级别API。它提供了比传统的阻塞I/O更好的性能和可伸缩性,特别是在处理大量连接或数据时。
NIO API的组成部分
NIO API由以下主要组件组成:
- 缓冲区(Buffers):用于在应用程序和底层操作系统之间传输数据的内存区域。
- 通道(Channels):抽象概念,表示应用程序和I/O设备之间的连接。
- 选择器(Selectors):用于轮询多个通道,以确定哪些通道已准备好读写。
NIO的工作原理
NIO的操作基于一个事件循环:
- 创建缓冲区和通道,初始化选择器。
- 在选择器上注册感兴趣的事件(例如,可读或可写)。
- 选择器轮询已注册的通道,以确定哪些通道已准备好处理数据。
- 当一个或多个通道准备好时,选择器会唤醒应用程序线程。
- 应用程序读取或写入数据,然后取消选择器上通道的注册。
实战案例
下面是一个使用NIO API编写简单服务器的示例:
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.ArrayList; import java.util.List; public class NIOServer { private static final int PORT = 8080; private static List<SocketChannel> connectedSockets = new ArrayList<>(); public static void main(String[] args) throws IOException { // 创建服务器套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); // 将服务器通道绑定到端口 serverSocketChannel.bind(new InetSocketAddress(PORT)); // 设置非阻塞模式 serverSocketChannel.configureBlocking(false); // 获取选择器 Selector selector = Selector.open(); // 将服务器通道注册到选择器,感兴趣的可接受事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 事件循环 while (true) { // 阻塞,直到至少有一个通道准备好 int readyChannels = selector.select(); // 如果没有准备好的通道,则继续 if (readyChannels == 0) { continue; } // 处理准备好的通道 for (SelectionKey key : selector.selectedKeys()) { // 可接受事件 if (key.isAcceptable()) { // 接受传入的连接 SocketChannel socketChannel = serverSocketChannel.accept(); // 设置非阻塞模式 socketChannel.configureBlocking(false); // 将套接字通道注册到选择器,感兴趣的可读事件 socketChannel.register(selector, SelectionKey.OP_READ); // 添加到已连接套接字列表 connectedSockets.add(socketChannel); } // 可读事件 else if (key.isReadable()) { SocketChannel socketChannel = (SocketChannel) key.channel(); // 读取数据 ByteBuffer buffer = ByteBuffer.allocate(1024); int bytesRead = socketChannel.read(buffer); // 如果读取到EOF,则关闭套接字 if (bytesRead == -1) { socketChannel.close(); connectedSockets.remove(socketChannel); } // 处理读取到的数据 // ... } } // 清除已处理的键 selector.selectedKeys().clear(); } } }
登录后复制
在这个例子中,服务器监听8080端口,并接受客户端连接。当一个客户端连接后,它将被添加到一个已连接套接字列表中。服务器使用选择器轮询已连接的套接字,以确定哪些套接字已准备好读写数据。
以上就是Java I/O流中的NIO API是如何工作的?的详细内容,更多请关注叮当号网其它相关文章!
文章来自互联网,只做分享使用。发布者:周斌,转转请注明出处:https://www.dingdanghao.com/article/346901.html