You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否存在等效于/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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:43:00