是否存在等效于/dev/null的ByteBuffer类?求现成实现方案
实现“黑洞”ByteBuffer的可行方案
嗨,这个需求我刚好折腾过!你说的这种「写入全丢弃、读取全返回0」的ByteBuffer,完全不用去碰那些具体实现类(比如DirectByteBuffer)搞不雅的取巧,咱们自己基于抽象类ByteBuffer写个极简实现就行,既符合规范又不浪费任何资源,还纯JDK跨平台。
核心思路
既然不需要存储任何数据,咱们的实现里根本不用维护缓冲区数组,只需要处理好position、limit、mark这几个状态变量,让所有操作的行为和标准ByteBuffer对齐:
- 写入操作:只更新position位置,不实际存储数据,超出limit时照样抛
BufferOverflowException - 读取操作:单个读取返回0,批量读取给目标数组填充全0,同时更新position,不够读时抛
BufferUnderflowException - 辅助方法(flip、clear、rewind等):完全遵循标准ByteBuffer的状态变更逻辑,保证行为一致
完整代码实现
import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.InvalidMarkException; public class BlackHoleByteBuffer extends ByteBuffer { private int position = 0; private int limit; private final int capacity; private int mark = -1; private BlackHoleByteBuffer(int capacity) { super(0, 0, capacity, capacity); this.capacity = capacity; this.limit = capacity; } // 对外提供的创建方法,和ByteBuffer.allocate对齐 public static ByteBuffer allocate(int capacity) { if (capacity < 0) { throw new IllegalArgumentException("Capacity cannot be negative"); } return new BlackHoleByteBuffer(capacity); } @Override public ByteBuffer slice() { return allocate(remaining()); } @Override public ByteBuffer duplicate() { BlackHoleByteBuffer dup = new BlackHoleByteBuffer(capacity); dup.position(position); dup.limit(limit); dup.mark = mark; return dup; } @Override public ByteBuffer asReadOnlyBuffer() { // 本身无数据,只读副本直接返回重复实例即可 return duplicate(); } @Override public byte get() { if (position >= limit) { throw new BufferUnderflowException(); } position++; return 0; } @Override public ByteBuffer get(byte[] dst) { return get(dst, 0, dst.length); } @Override public ByteBuffer get(byte[] dst, int offset, int length) { int remaining = remaining(); int actualRead = Math.min(length, remaining); if (actualRead > 0) { // 给目标数组填充全0 java.util.Arrays.fill(dst, offset, offset + actualRead, (byte) 0); position += actualRead; } else if (length > remaining) { throw new BufferUnderflowException(); } return this; } @Override public ByteBuffer put(byte b) { if (position >= limit) { throw new BufferOverflowException(); } position++; return this; } @Override public ByteBuffer put(byte[] src) { return put(src, 0, src.length); } @Override public ByteBuffer put(byte[] src, int offset, int length) { int remaining = remaining(); int actualWrite = Math.min(length, remaining); if (actualWrite > 0) { position += actualWrite; } else if (length > remaining) { throw new BufferOverflowException(); } return this; } @Override public ByteBuffer put(ByteBuffer src) { int writeLength = src.remaining(); return put(new byte[writeLength], 0, writeLength); } @Override public byte get(int index) { if (index < 0 || index >= limit) { throw new IndexOutOfBoundsException("Index: " + index + ", Limit: " + limit); } return 0; } @Override public ByteBuffer put(int index, byte b) { if (index < 0 || index >= limit) { throw new IndexOutOfBoundsException("Index: " + index + ", Limit: " + limit); } // 无需实际存储,直接返回即可 return this; } @Override public int capacity() { return capacity; } @Override public int position() { return position; } @Override public ByteBuffer position(int newPosition) { if (newPosition < 0 || newPosition > limit) { throw new IllegalArgumentException("Position: " + newPosition + ", Limit: " + limit); } position = newPosition; if (mark > position) { mark = -1; } return this; } @Override public int limit() { return limit; } @Override public ByteBuffer limit(int newLimit) { if (newLimit < 0 || newLimit > capacity) { throw new IllegalArgumentException("Limit: " + newLimit + ", Capacity: " + capacity); } limit = newLimit; if (position > limit) { position = limit; } if (mark > limit) { mark = -1; } return this; } @Override public ByteBuffer mark() { mark = position; return this; } @Override public ByteBuffer reset() { if (mark == -1) { throw new InvalidMarkException(); } position = mark; return this; } @Override public ByteBuffer clear() { position = 0; limit = capacity; mark = -1; return this; } @Override public ByteBuffer flip() { limit = position; position = 0; mark = -1; return this; } @Override public ByteBuffer rewind() { position = 0; mark = -1; return this; } @Override public int remaining() { return limit - position; } @Override public boolean hasRemaining() { return position < limit; } @Override public boolean isReadOnly() { return false; } @Override public boolean isDirect() { return false; } }
使用说明
用起来和普通ByteBuffer完全一样:
// 创建一个容量为1024的黑洞ByteBuffer ByteBuffer blackHole = BlackHoleByteBuffer.allocate(1024); // 写入数据,正常执行但数据被丢弃 blackHole.put("Hello World".getBytes()); blackHole.flip(); // 读取数据,返回全0 byte[] buf = new byte[11]; blackHole.get(buf); // buf里全是0
这个实现完全遵循JDK ByteBuffer的规范,没有任何第三方依赖,跨平台肯定没问题。如果不想自己写,部分开源工具库可能有类似实现,但自己写的版本最可控,也不用引入额外依赖。
内容的提问来源于stack exchange,提问作者Wisteso
相关产品推荐
相关产品推荐

