java如何使用nio
Java NIO 基础概念
Java NIO(New I/O)是一种基于通道(Channel)和缓冲区(Buffer)的高效I/O模型,支持非阻塞操作和选择器(Selector)机制,适用于高并发场景。
核心组件
缓冲区(Buffer)
缓冲区是数据的临时存储区,分为多种类型(如 ByteBuffer、CharBuffer)。通过 allocate() 方法创建:
ByteBuffer buffer = ByteBuffer.allocate(1024); // 分配1024字节的缓冲区
通道(Channel)
通道是数据双向传输的管道,常见实现类包括 FileChannel、SocketChannel 和 ServerSocketChannel。
文件读写示例
通过 FileChannel 读写文件:
try (FileChannel channel = FileChannel.open(Paths.get("test.txt"), StandardOpenOption.READ)) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer); // 读取数据到缓冲区
buffer.flip(); // 切换为读模式
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
} catch (IOException e) {
e.printStackTrace();
}
非阻塞网络通信
使用 Selector 实现非阻塞Socket通信:
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT); // 注册接受连接事件
while (true) {
selector.select(); // 阻塞直到有事件就绪
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
if (key.isAcceptable()) {
SocketChannel client = serverChannel.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ); // 注册读事件
} else if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(128);
client.read(buffer);
buffer.flip();
System.out.println("Received: " + new String(buffer.array()));
}
iter.remove();
}
}
内存映射文件
通过 FileChannel.map() 实现高效大文件处理:

try (FileChannel channel = FileChannel.open(Paths.get("large.bin"),
StandardOpenOption.READ, StandardOpenOption.WRITE)) {
MappedByteBuffer mappedBuffer = channel.map(
FileChannel.MapMode.READ_WRITE, 0, channel.size());
mappedBuffer.putInt(0, 123); // 直接修改文件内容
} catch (IOException e) {
e.printStackTrace();
}
注意事项
- 缓冲区状态管理:调用
flip()、clear()或rewind()切换读写模式。 - 资源释放:确保通道和选择器通过
try-with-resources或手动关闭。 - 性能优化:使用直接缓冲区(
ByteBuffer.allocateDirect())减少JVM堆内存拷贝开销。






