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

Java NIO 学习小记

Java NIO 学习小记 :Buffer、Channel 与 Selector

在 Java 的 I/O 体系中,NIO(New Input/Output)是对传统 BIO(Blocking I/O)的优化。NIO 提供了更高效的 面向缓冲区、基于通道 的数据处理方式,并且通过 多路复用器(Selector) 实现了单线程处理多个连接的能力。本文简单记录 NIO 的核心概念与常用方法。


一、NIO 的三大核心组件

1. Buffer(缓冲区)

Buffer 是 NIO 中存储数据的容器,底层是数组,但提供了更强大的数据操作能力。所有读写操作都需要通过 Buffer。

常见类型:

  • ByteBuffer(最常用,网络传输、文件读写)
  • CharBuffer
  • IntBuffer
  • LongBuffer
  • DoubleBuffer
  • FloatBuffer
  • ShortBuffer

核心方法:

  • put():写入数据到缓冲区
  • get():从缓冲区读取数据
  • flip():写模式切换为读模式
  • clear():清空缓冲区(仅重置指针,不清除数据)
  • rewind():回到开头重新读取
  • mark() / reset():标记和回滚
  • remaining():返回可读数据量

2. Channel(通道)

Channel 类似于传统的流(Stream),但支持双向操作(可读可写),并且必须配合 Buffer 使用。

常见实现:

  • FileChannel:文件 I/O
  • SocketChannel:TCP 客户端
  • ServerSocketChannel:TCP 服务端
  • DatagramChannel:UDP 通信

常用方法:

  • read(ByteBuffer buffer):从通道读入数据到 Buffer
  • write(ByteBuffer buffer):从 Buffer 写数据到通道
  • close():关闭通道
  • open():打开通道(如 FileChannel.open()

3. Selector(选择器)

Selector 是 NIO 的核心,用于管理多个通道,支持非阻塞 IO。通过一个线程就能高效处理成百上千的连接。

常用方法:

  • open():打开一个选择器
  • select():阻塞直到有通道就绪
  • selectNow():非阻塞立即返回
  • selectedKeys():获取就绪通道集合
  • register(channel, ops):注册通道并监听事件

事件类型:

  • OP_ACCEPT:连接就绪
  • OP_CONNECT:连接建立
  • OP_READ:可读
  • OP_WRITE:可写

二、NIO 的 I/O 模型

  1. BIO(同步阻塞):一个连接一个线程,效率低。
  2. NIO(同步非阻塞):一个线程管理多个连接,配合 Selector 实现多路复用。
  3. AIO(异步非阻塞):Java 7 引入,基于回调机制,I/O 完成后自动通知。

三、例子

1. FileChannel + Buffer 示例

import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;public class NIOFileExample {public static void main(String[] args) throws Exception {RandomAccessFile file = new RandomAccessFile("test.txt", "rw");FileChannel channel = file.getChannel();ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = channel.read(buffer);while (bytesRead != -1) {buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}buffer.clear();bytesRead = channel.read(buffer);}channel.close();file.close();}
}

2. Selector 示例(简易 TCP 服务端)

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;public class NIOServer {public static void main(String[] args) throws Exception {Selector selector = Selector.open();ServerSocketChannel server = ServerSocketChannel.open();server.bind(new InetSocketAddress(8080));server.configureBlocking(false);server.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();Iterator<SelectionKey> keys = selector.selectedKeys().iterator();while (keys.hasNext()) {SelectionKey key = keys.next();keys.remove();if (key.isAcceptable()) {SocketChannel client = server.accept();client.configureBlocking(false);client.register(selector, SelectionKey.OP_READ);System.out.println("客户端连接:" + client.getRemoteAddress());} else if (key.isReadable()) {SocketChannel client = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int len = client.read(buffer);if (len > 0) {buffer.flip();System.out.println("收到消息:" + new String(buffer.array(), 0, len));client.write(ByteBuffer.wrap("已收到\\n".getBytes()));}}}}}
}

四、总结

  • Buffer:数据容器,提供丰富的操作方法。
  • Channel:数据通道,配合 Buffer 使用。
  • Selector:多路复用器,非阻塞 IO 的关键。

NIO 提供了比 BIO 更高效的方式来处理网络和文件 I/O,是理解 Netty 等高性能网络框架的基础。

http://www.wxhsa.cn/company.asp?id=3634

相关文章:

  • 扩展欧几里得算法求乘法逆元
  • redis实现缓存3-封装redis工具类
  • 高阻态
  • 鸿蒙应用开发从入门到实战(四):ArkTS 语言概述
  • 命令模式的深度解析:从标准实现到TPL Dataflow高性能架构
  • JavaWeb
  • 读书笔记:为什么数据在磁盘上的存放顺序如此重要?
  • Rcc_APBPeriphClockCmd()
  • 故障处理:ORA-19809: limit exceeded for recovery files
  • ORA-01555系列:二、ORA-01555的场景分析与解决方案
  • PySimpleGUI常用控件
  • 25.09.14 与其感慨路难行,不如马上出发
  • GCC工具链应用学习笔记
  • 初始化 MCP 环境 创建 MCP Server (一)
  • 博客园格式设置
  • [总结/备赛]备战 CSP-S 2025 初赛总结
  • win11 系统如何进行硬盘分区?固态硬盘怎么分区?SSD 固态硬盘是分区好还是不分区好?
  • 逆序数及其应用
  • 豆豆守护如何下载?
  • Java运行时jar时终端输出的中文日志是乱码
  • ZK2真空发生器日常清理
  • Nacos服务注册与发现
  • 马的遍历
  • 20231310王宏邦《密码系统设计》第1周
  • 新学期第一次随笔:慢慢学,总会有进步
  • 详细介绍:【C语言】第四课 指针与内存管理
  • 知识点错题整理
  • 202311_陇剑杯预赛_tcpdump
  • Linux学习记录(六):添加/删除用户
  • python 链式调用 合并 __setattr__ __getattribute__ in nested object()