java nio中buffer.put()不直接支持动态合并字节缓冲区,但可通过正确管理position、limit和capacity实现:先flip源buffer确保可读,再分配足够容量的新buffer或复用现有buffer(需clear且容量充足),最后调用put完成合并。

Java NIO 中,Buffer.put() 本身不直接支持“动态合并两个字节缓存区”,但可以通过合理操作 ByteBuffer 实现高效、安全的合并——关键在于正确管理位置(position)、限制(limit)和容量(capacity),避免越界或数据覆盖。
理解 ByteBuffer 的状态与 put 的行为
put(byte[] src) 或 put(ByteBuffer src) 会从当前 position 开始写入,并自动递增 position。若目标 buffer 容量不足或未重置状态,会抛出 BufferOverflowException 或静默丢弃数据。
- 合并前必须确保目标 buffer 有足够剩余空间:
remaining() = limit - position - 调用
put前,通常需调用flip()(读模式转写模式)或手动clear()/compact()重置位置 - 不能直接对只读 buffer 或已满 buffer 调用
put
方法一:分配新 buffer,一次性合并(推荐)
最安全、清晰的方式是创建一个容量足够大的新 ByteBuffer,分别 put 两个源 buffer 的内容(需先 flip() 确保可读):
ByteBuffer buf1 = ByteBuffer.allocate(4).put(new byte[]{1,2});
ByteBuffer buf2 = ByteBuffer.allocate(4).put(new byte[]{3,4,5});
<p>// 重置读取位置
buf1.flip();
buf2.flip();</p><p>// 分配新 buffer,容量为两者 remaining() 之和
int totalLen = buf1.remaining() + buf2.remaining();
ByteBuffer merged = ByteBuffer.allocate(totalLen);</p><p>// 依次 put(自动更新 position)
merged.put(buf1).put(buf2); // 链式调用,返回自身</p><p>// 合并后记得 flip() 才能读取
merged.flip();
</p>
方法二:复用已有 buffer(需谨慎扩容)
若想复用某个现有 buffer(如作为“累积缓冲区”),需确保其 capacity ≥ 总长度。NIO buffer 不支持动态扩容,所以实际中常配合 ByteBuffer.array() 或使用 ByteArrayOutputStream 预处理:
- 如果原 buffer 是 heap buffer 且有足够容量:调用
clear()→put(buf1)→put(buf2) - 如果容量不够,只能新建;试图
put超出 capacity 会抛异常 - 不可靠做法:用
wrap(new byte[...])包装外部数组再 put —— 这本质仍是新建
常见陷阱与避坑建议
容易出错的地方不是语法,而是状态管理:
- 忘记
flip():源 buffer 若刚写完没 flip,remaining()为 0,put(buf)不写入任何数据 - 重复 put 同一个 buffer:第二次 put 时 position 已到末尾,导致写入 0 字节
- 混用相对/绝对 put:如
put(int index, byte b)不影响 position,而put(byte)会改变 position,状态易混乱 - Direct buffer 合并:不能直接 array(),需用
get()拷贝到 heap buffer 再合并
不复杂但容易忽略细节——核心就是:先确保可读(flip),再确保可写(clear/足够容量),最后 put。不需要额外工具类,标准 API 就够用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











