Java 如何将 OutputStream 中的数据放入 ByteBuffer?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2716596/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to put data from an OutputStream into a ByteBuffer?
提问by Rasto
In Java I need to put content from an OutputStream (I fill data to that stream myself) into a ByteBuffer. How to do it in a simple way?
在 Java 中,我需要将内容从 OutputStream(我自己将数据填充到该流)中放入 ByteBuffer。如何以简单的方式做到这一点?
采纳答案by DJClayworth
You can create a ByteArrayOutputStream
and write to it, and extract the contents as a byte[]
using toByteArray()
. Then ByteBuffer.wrap(byte [])
will create a ByteBuffer
with the contents of the output byte array.
您可以创建一个ByteArrayOutputStream
并写入它,并将内容提取为byte[]
using toByteArray()
。然后ByteBuffer.wrap(byte [])
将ByteBuffer
使用输出字节数组的内容创建一个。
回答by Marcus Adams
Try using PipedOutputStream instead of OutputStream. You can then connect a PipedInputStream to read the data back out of the PipedOutputStream.
尝试使用 PipedOutputStream 而不是 OutputStream。然后,您可以连接 PipedInputStream 以从 PipedOutputStream 中读取数据。
回答by mark
There is a more efficient variant of @DJClayworth's answer.
@DJClayworth 的答案有一个更有效的变体。
As @seh correctly noticed, ByteArrayOutputStream.toByteArray()
returns a copyof the backing byte[]
object, which may be inefficient. However, the backing byte[]
object as well as the count of the bytes are both protected members of the ByteArrayOutputStream
class. Hence, you can create your own variant of the ByteArrayOutputStream exposing them directly:
正如@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;
}
}
Using this class is easy:
使用这个类很容易:
MyByteArrayOutputStream out = new MyByteArrayOutputStream();
fillTheOutputStream(out);
return new ByteArrayInputStream(out.getBuf(), 0, out.getCount());
As a result, once all the output is written the same buffer is used as the basis of an input stream.
因此,一旦所有输出都被写入,同一个缓冲区将用作输入流的基础。
回答by RoboAlex
Though the above-mention answers solve your problem, none of them are efficient as you expect from NIO. ByteArrayOutputStream or MyByteArrayOutputStream first write the data into a Java heap memory and then copy it to ByteBuffer which greatly affects the performance.
尽管上述答案解决了您的问题,但它们都没有您对 NIO 的期望有效。ByteArrayOutputStream 或 MyByteArrayOutputStream 首先将数据写入 Java 堆内存,然后将其复制到 ByteBuffer,这极大地影响了性能。
An efficient implementation would be writing ByteBufferOutputStream class yourself. Actually It's quite easy to do. You have to just provide a write() method. See this link for ByteBufferInputStream.
一个有效的实现是自己编写 ByteBufferOutputStream 类。其实这很容易做到。你只需要提供一个 write() 方法。有关ByteBufferInputStream ,请参阅此链接。
回答by MeetTitan
You say you're writing to this stream yourself? If so, maybe you could implement your own ByteBufferOutputStream and plug n' play.
你说你自己在写这个流?如果是这样,也许您可以实现自己的 ByteBufferOutputStream 并即插即用。
The base class would look like so:
基类看起来像这样:
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();
}
/*
}
回答by Yessy
// access the protected member buf& countfrom the extend class
//从扩展类访问受保护的成员buf& count
class ByteArrayOutputStream2ByteBuffer extends ByteArrayOutputStream {
public ByteBuffer toByteBuffer() {
return ByteBuffer.wrap(buf, 0, count);
}
}