如何将OutputStream中的数据放入ByteBuffer?

时间:2010-04-26 20:23:33

标签: java outputstream bytebuffer

在Java中,我需要将OutputStream中的内容(我自己将数据填充到该流中)放入ByteBuffer中。如何以简单的方式做到这一点?

6 个答案:

答案 0 :(得分:32)

您可以创建ByteArrayOutputStream并对其进行写入,然后使用byte[]将内容解压缩为toByteArray()。然后ByteBuffer.wrap(byte [])将创建一个ByteBuffer,其中包含输出字节数组的内容。

答案 1 :(得分:21)

@ DJClayworth的答案有一个更有效的变体。

正如@seh正确注意到的那样,ByteArrayOutputStream.toByteArray()会返回支持byte[]对象的副本,这可能效率低下。但是,后备byte[]对象以及字节数都是ByteArrayOutputStream类的受保护成员。因此,您可以创建自己的ByteArrayOutputStream变体直接公开它们:

public class MyByteArrayOutputStream extends ByteArrayOutputStream {
  public MyByteArrayOutputStream() {
  }

  public MyByteArrayOutputStream(int size) {
    super(size);
  }

  public int getCount() {
    return count;
  }

  public byte[] getBuf() {
    return buf;
  }
}

使用此类很简单:

MyByteArrayOutputStream out = new MyByteArrayOutputStream();
fillTheOutputStream(out);
return new ByteArrayInputStream(out.getBuf(), 0, out.getCount());

因此,一旦写入所有输出,就会使用相同的缓冲区作为输入流的基础。

答案 2 :(得分:5)

虽然上面提到的答案可以解决您的问题,但是没有一个能像您对NIO的期望那样高效。 ByteArrayOutputStream或MyByteArrayOutputStream首先将数据写入Java堆内存,然后将其复制到ByteBuffer,这会极大地影响性能。

一个有效的实现是自己编写ByteBufferOutputStream类。实际上这很容易做到。你必须提供一个write()方法。请参阅ByteBufferInputStream的此链接。

答案 3 :(得分:1)

尝试使用PipedOutputStream而不是OutputStream。然后,您可以连接PipedInputStream以从PipedOutputStream中读取数据。

答案 4 :(得分:0)

您说自己正在写此信息流吗?如果是这样,也许您可​​以实现自己的ByteBufferOutputStream并即插即用。

基类如下:

public class ByteBufferOutputStream extends OutputStream {
    //protected WritableByteChannel wbc; //if you need to write directly to a channel
    protected static int bs = 2 * 1024 * 1024; //2MB buffer size, change as needed
    protected ByteBuffer bb = ByteBuffer.allocate(bs);

    public ByteBufferOutputStream(...) {
        //wbc = ... //again for writing to a channel
    }

    @Override
    public void write(int i) throws IOException {
        if (!bb.hasRemaining()) flush();
        byte b = (byte) i;
        bb.put(b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        if (bb.remaining() < len) flush();
        bb.put(b, off, len);
    }

    /* do something with the buffer when it's full (perhaps write to channel?)
    @Override
    public void flush() throws IOException {
        bb.flip();
        wbc.write(bb);
        bb.clear();
    }

    @Override
    public void close() throws IOException {
        flush();
        wbc.close();
    }
    /*
}

答案 5 :(得分:0)

///从扩展类访问受保护成员 buf count

class ByteArrayOutputStream2ByteBuffer extends ByteArrayOutputStream {
    public ByteBuffer toByteBuffer() {
        return ByteBuffer.wrap(buf, 0, count);
    }
}