当前位置: 首页 > news >正文

【Java】NIO 简单介绍

简介

  • 从 Java 1.4 版本开始引入的一个新的 I/O API,可以替代标准的 Java I/O。
  • 提供了与标准 I/O 不同的工作方式,核心是 通道(Channel)、缓冲区(Buffer) 和 选择器(Selector)。
  • 支持非阻塞 I/O 操作,非常适合处理大量并发连接,是构建高性能网络应用的基础。
  • 多路复用的机制,适合构建高性能服务器应用

核心概念

  • Channel:类似于流(Stream),但可以双向读写
  • Buffer:一个用于存储数据的容器(本质上是一个数组)
  • Selector:用于监听多个 Channel 的事件(如连接、读就绪、写就绪)
    • 一个线程可以管理多个 Channel,实现单线程处理多路复用,极大地提高了 I/O 效率

代码示例

public class NIOClient {public static void main(String[] args) throws IOException {// 1. 连接到服务器SocketChannel socketChannel = SocketChannel.open();socketChannel.connect(new InetSocketAddress("localhost", 8080));socketChannel.configureBlocking(false); // 设置为非阻塞(可选,这里为了演示NIO风格)System.out.println("已连接到服务器 localhost:8080");System.out.println("请输入消息(输入 'quit' 退出):");// 用于读取用户输入BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String userInput;// 用于读取服务器响应ByteBuffer buffer = ByteBuffer.allocate(1024);while ((userInput = reader.readLine()) != null) {if ("quit".equalsIgnoreCase(userInput)) {break;}// 2. 发送消息到服务器byte[] messageBytes = userInput.getBytes();ByteBuffer writeBuffer = ByteBuffer.wrap(messageBytes);socketChannel.write(writeBuffer);System.out.println("已发送: " + userInput);// 3. 读取服务器的响应buffer.clear(); // 清空缓冲区,准备接收数据int bytesRead = socketChannel.read(buffer);if (bytesRead > 0) {buffer.flip(); // 切换为读模式byte[] responseBytes = new byte[buffer.remaining()];buffer.get(responseBytes);String response = new String(responseBytes);System.out.println("服务器回复: " + response);}}// 4. 关闭连接socketChannel.close();System.out.println("客户端已关闭。");}
}
public class NIOServer {public static void main(String[] args) throws IOException {// 1. 打开 SelectorSelector selector = Selector.open();// 2. 打开 ServerSocketChannelServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.configureBlocking(false); // 设置为非阻塞模式serverChannel.bind(new InetSocketAddress(8080));// 3. 将 ServerSocketChannel 注册到 Selector,监听 ACCEPT 事件serverChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("NIO 服务器启动,监听端口 8080...");while (true) {// 4. 阻塞等待,直到有事件发生int readyChannels = selector.select();if (readyChannels == 0) continue;// 5. 获取就绪的 SelectionKey 集合Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> keyIterator = selectedKeys.iterator();while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();// 6. 处理不同的事件if (key.isAcceptable()) {// 接受新的连接ServerSocketChannel server = (ServerSocketChannel) key.channel();SocketChannel clientChannel = server.accept();clientChannel.configureBlocking(false); // 设置为非阻塞clientChannel.register(selector, SelectionKey.OP_READ);System.out.println("新客户端连接: " + clientChannel.getRemoteAddress());} else if (key.isReadable()) {// 读取客户端数据SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(256);int bytesRead = clientChannel.read(buffer);if (bytesRead > 0) {buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);String message = new String(data);System.out.println("收到消息: " + message);// 回复客户端ByteBuffer responseBuffer = ByteBuffer.wrap(("Echo: " + message).getBytes());clientChannel.write(responseBuffer);} else if (bytesRead == -1) {// 客户端关闭连接System.out.println("客户端断开: " + clientChannel.getRemoteAddress());clientChannel.close();}}// 7. 移除已处理的 keykeyIterator.remove();}}}

文章转载自:

http://L222q1d2.wqbbc.cn
http://ifLYT8fq.wqbbc.cn
http://1ctyvwaR.wqbbc.cn
http://uCitIUyN.wqbbc.cn
http://4cg53wmv.wqbbc.cn
http://9xCDg2Cg.wqbbc.cn
http://T6rxhG28.wqbbc.cn
http://vLoeotyC.wqbbc.cn
http://5H3uMmP2.wqbbc.cn
http://88xlHdIk.wqbbc.cn
http://xVRTrwRI.wqbbc.cn
http://5OZVPXLb.wqbbc.cn
http://aP53gwVL.wqbbc.cn
http://0wmjERIa.wqbbc.cn
http://rIJ1I5EI.wqbbc.cn
http://ziqcGeXI.wqbbc.cn
http://vcnvZm45.wqbbc.cn
http://S5hmDbGN.wqbbc.cn
http://MrzOLwAN.wqbbc.cn
http://vZYfaY4T.wqbbc.cn
http://vwn5sfIf.wqbbc.cn
http://fK2w8Mdx.wqbbc.cn
http://BY1B3j1P.wqbbc.cn
http://Bu3rX6Wj.wqbbc.cn
http://8mQSmYV5.wqbbc.cn
http://29tCtn8F.wqbbc.cn
http://KRIwVUPn.wqbbc.cn
http://b7TonpjU.wqbbc.cn
http://Cl5UOlzi.wqbbc.cn
http://UwmcU6Qe.wqbbc.cn
http://www.dtcms.com/a/375183.html

相关文章:

  • Qt从小白到进阶:完整学习路线与资源指南(补充)
  • 结合大数据知识体系对仓库建模方法总结
  • AI 辅助文档生成:从接口注释到自动化 API 文档上线
  • Day 18: 多模态大模型专项 - 理论深度与面试精通之路
  • Flink Checkpoint失败问题分析与解决方案
  • Flyway:一款免费开源的数据库变更管理工具
  • 如何开发一个教育性质的多线程密码猜测演示器
  • 基于MATLAB的线性判别分析(LDA)人脸识别实现
  • iOS现有项目采用混合工程方式集成RN0.77.3版本
  • 软件设置linux时区,Linux设置和修改时间与时区
  • 系统架构设计师备考第18天——信息安全基础知识
  • 嵌入式系统学习Day36(简单的网页制作)
  • 【人工智能99问】GPT4与QWen3的对比(39/99)
  • 计组中央处理器刷题
  • 熊大熊二与糖果2
  • 元宇宙与零售业变革:沉浸式体验重构消费全链路
  • 运筹学——对偶单纯形法,目标函数系数的敏感性分析
  • 考研复习-计算机网络-第四章-网络层
  • 《UE5_C++多人TPS完整教程》学习笔记49 ——《P50 应用瞄准偏移(Applying Aim Offset)》
  • 微信小程序罗盘功能开发指南
  • 【C++进阶】---- map和set的使用
  • [差分数组]2327. 知道秘密的人数
  • 微调Qwen2.5模型的完整指南
  • SpringBoot之日志处理(logback和AOP记录操作日志)
  • DTO简单讲解
  • ERP和MES、WMS、CRM,到底怎么配合?
  • 【实战中提升自己】总部项目实施全方面总结
  • MS9127S USB投屏控制芯片(LVDS输出)
  • rook-ceph的osd块存储权重数据迁移脚本
  • 少儿编程C++快速教程之——3. 数组和矩阵操作