java - ¿Cómo colocar datos de un OutputStream en un ByteBuffer?
(5)
¿Dices que estás escribiendo a este flujo tú mismo? Si es así, tal vez podría implementar su propio ByteBufferOutputStream y plug n ''play.
La clase base se vería así:
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();
}
/*
}
En Java necesito poner contenido de un OutputStream (yo mismo lleno los datos en esa secuencia) en un ByteBuffer. ¿Cómo hacerlo de una manera sencilla?
Aunque las respuestas mencionadas anteriormente resuelven su problema, ninguna de ellas es tan eficiente como espera de NIO. ByteArrayOutputStream o MyByteArrayOutputStream primero escriben los datos en una memoria de almacenamiento dinámico de Java y luego los copian en ByteBuffer, lo que afecta en gran medida el rendimiento.
Una implementación eficiente sería escribir la clase ByteBufferOutputStream usted mismo. En realidad es bastante fácil de hacer. Sólo tienes que proporcionar un método de escritura (). Vea este enlace para ByteBufferInputStream .
Hay una variante más eficiente de la respuesta de @ DJClayworth.
Como @seh notó correctamente, ByteArrayOutputStream.toByteArray()
devuelve una copia del objeto byte[]
respaldo, que puede ser ineficiente. Sin embargo, tanto el objeto byte[]
respaldo como el conteo de bytes son miembros protegidos de la clase ByteArrayOutputStream
. Por lo tanto, puede crear su propia variante del ByteArrayOutputStream exponiéndolos directamente:
public class MyByteArrayOutputStream extends ByteArrayOutputStream {
public MyByteArrayOutputStream() {
}
public MyByteArrayOutputStream(int size) {
super(size);
}
public int getCount() {
return count;
}
public byte[] getBuf() {
return buf;
}
}
Usar esta clase es fácil:
MyByteArrayOutputStream out = new MyByteArrayOutputStream();
fillTheOutputStream(out);
return new ByteArrayInputStream(out.getBuf(), 0, out.getCount());
Como resultado, una vez que se escribe toda la salida, se utiliza el mismo búfer como base de un flujo de entrada.
Intente usar PipedOutputStream en lugar de OutputStream. Luego puede conectar un PipedInputStream para volver a leer los datos del PipedOutputStream.
Puede crear un ByteArrayOutputStream
y escribir en él, y extraer el contenido como un byte[]
utilizando toByteArray()
. Luego, ByteBuffer.wrap(byte [])
creará un ByteBuffer
con el contenido de la matriz de bytes de salida.