gatheringbytechannel是java nio中支持聚集写的通道接口,允许按顺序一次性写入多个bytebuffer;常见实现有socketchannel和write模式的filechannel,调用write(bytebuffer[])即可批量写入。

GatheringByteChannel 是 Java NIO 中支持“聚集写”(gather write)的通道接口,它允许你把多个 ByteBuffer 的数据**按顺序一次性写入**到通道中,而无需手动拼接或多次调用 write()。常见实现类包括 SocketChannel、FileChannel(仅限写模式)等。
哪些通道支持 GatheringByteChannel
不是所有通道都支持聚集写。需满足两个条件:
- 通道必须是可写的(如
SocketChannel.open().configureBlocking(false)后连接成功,或FileChannel.open(..., WRITE)) - 通道类型需实现
GatheringByteChannel接口 —— 常见的有:
✓ SocketChannel(客户端/服务端写)
✓ FileChannel(以 WRITE 模式打开)
✗ ServerSocketChannel、Pipe.SinkChannel、DatagramChannel(不支持 gather)
怎么用 write(ByteBuffer[] ) 进行批量写入
最直接的方式是调用 write(ByteBuffer[]) 方法,传入一个非空的 buffer 数组:
- 数组中每个
ByteBuffer必须处于 读模式(即buffer.flip()或buffer.limit(position).position(0)已调用) - 写入顺序严格按数组下标从 0 到 n-1,数据连续追加
- 返回值是本次实际写入的总字节数(可能小于所有 buffer 的剩余字节之和,尤其在非阻塞模式下)
- 被写过的 buffer 的 position 会自动前移,limit 不变;未写满的 buffer 仍保留在原状态
示例:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
ByteBuffer header = ByteBuffer.allocate(4).putInt(0x12345678).flip();
ByteBuffer body = StandardCharsets.UTF_8.encode("Hello NIO");
ByteBuffer[] bufs = { header, body };
int totalWritten = channel.write(bufs); // 一次性写入 header + body
注意非阻塞模式下的写入行为
在非阻塞 I/O 中(如 SocketChannel.configureBlocking(false)),write(bufs) 可能只写入部分数据:
- 返回值为 0 表示当前内核缓冲区已满,需等待就绪后重试
- 不会抛出异常,也不会阻塞线程
- 你需要自己管理未写完的 buffer:记录已写偏移、截取剩余部分、下次继续提交
- 推荐配合
Selector使用,在OP_WRITE就绪时再尝试写入剩余数据
更灵活的写法:write(ByteBuffer[], int, int)
如果不想每次都传整个数组,可以用带索引范围的重载方法:
-
write(bufs, offset, length):只写数组中从offset开始的length个 buffer - 适合动态构造写入序列,比如跳过空 buffer 或按优先级分批提交
- 同样要求指定范围内的每个 buffer 处于读模式
例如跳过第一个空 header,只写 body 和 footer:
ByteBuffer[] all = { header, body, footer };
// 假设 header.remaining() == 0,则跳过它
int written = channel.write(all, 1, 2); // 写 body 和 footer
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










