使用输入流包装字节缓冲区

2022-08-31 17:12:49

我有一个方法,它采用输入流并从中读取数据。我也想将此方法与字节缓冲器一起使用。有没有办法包装字节缓冲区,以便可以将其作为流访问?


答案 1

Thilo引用的实现似乎存在一些错误,并且还逐字复制并粘贴到其他站点上:

  1. ByteBufferBackedInputStream.read()返回它读取的字节的符号扩展 int 表示形式,这是错误的(值应在范围 [-1..255]内)
  2. ByteBufferBackedInputStream.read(byte[], int, int)当缓冲区中没有剩余字节时,不返回 -1,根据 API 规范

ByteBufferBackedOutputStream似乎相对合理。

我在下面提供了一个“固定”版本。如果我发现更多错误(或有人指出它们),我会在这里更新它。

更新:从读/写方法中删除了关键字synchronized

输入流

public class ByteBufferBackedInputStream extends InputStream {

    ByteBuffer buf;

    public ByteBufferBackedInputStream(ByteBuffer buf) {
        this.buf = buf;
    }

    public int read() throws IOException {
        if (!buf.hasRemaining()) {
            return -1;
        }
        return buf.get() & 0xFF;
    }

    public int read(byte[] bytes, int off, int len)
            throws IOException {
        if (!buf.hasRemaining()) {
            return -1;
        }

        len = Math.min(len, buf.remaining());
        buf.get(bytes, off, len);
        return len;
    }
}

输出流

public class ByteBufferBackedOutputStream extends OutputStream {
    ByteBuffer buf;

    public ByteBufferBackedOutputStream(ByteBuffer buf) {
        this.buf = buf;
    }

    public void write(int b) throws IOException {
        buf.put((byte) b);
    }

    public void write(byte[] bytes, int off, int len)
            throws IOException {
        buf.put(bytes, off, len);
    }

}

答案 2

JDK中没有任何内容,但是有很多实现,谷歌的ByteBufferInputStream。基本上,它们将一个或多个字节缓冲器包装在一起,并在其中跟踪索引,该索引记录了已经读取了多少。像这样的东西经常出现,但显然是错误的,请参阅@Mike休斯顿的答案改进版本)。


推荐