2021-12-27 13:18:42
Java NIO(New I/O)通过Buffer和Channel实现高性能I/O操作,尤其适用于高并发和大数据场景。以下是核心组件的详细解析及使用方法:

Buffer是NIO中存储数据的容器,所有Channel的读写操作均通过Buffer完成。
1. Buffer类型clear():重置所有属性(用于重新写入)。
compact():保留未读数据,将剩余空间移至Buffer开头。
Channel替代传统IO流,支持双向数据传输,必须与Buffer配合使用。
1. 常见Channel类型数据读取:Channel → Buffer
调用channel.read(buffer)将数据存入Buffer。
必须调用flip()切换为读模式后才能读取数据。
数据写入:Buffer → Channel
填充Buffer后,调用channel.write(buffer)将数据写入Channel。
写入前需确保Buffer处于写入模式(通过clear()或compact()重置)。
Buffer大小设置
过小导致频繁I/O操作,过大浪费内存。建议根据数据量动态调整。
模式切换错误
忘记调用flip()会导致读取不到数据,clear()未调用会残留旧数据。
直接Buffer vs 非直接Buffer
直接Buffer:通过allocateDirect()创建,减少数据拷贝,但创建成本高,适合长期使用场景。
非直接Buffer:通过allocate()创建,由JVM管理内存,灵活性更高。
复用Buffer
连续操作时,需通过clear()或compact()重置Buffer状态。
文件高效读写
使用FileChannel和ByteBuffer实现零拷贝文件复制。
网络通信
通过SocketChannel发送/接收数据包,支持非阻塞模式。
非阻塞IO
结合Selector监听多个Channel的读写事件,实现单线程管理多连接。
问题:读取数据为空。原因:未调用flip()或position未重置。解决:检查模式切换逻辑。
问题:内存占用过高。原因:直接Buffer未及时释放。解决:显式调用cleaner()(需谨慎)或优化Buffer生命周期。

掌握Buffer和Channel的核心机制后,可进一步探索Selector实现多路复用,或结合内存映射文件(MappedByteBuffer)优化大文件处理。实际开发中需根据场景权衡性能与资源消耗。