2010-11-01 8 views
9

¿Hay alguna razón sutil por la cual java.nio.ByteBuffer no implementa java.io.DataOutput o java.io.DataInput, o los autores simplemente no optaron por hacer esto? Parecería sencillo mapear las llamadas (por ejemplo, putInt() -> writeInt()).¿Podría ByteBuffer implementar DataOutput/DataInput?

El problema básico I (y algunos others, al parecer) tienen es las clases más antiguas que saben cómo serializar/serializar a sí mismos utilizando las interfaces genéricas: DataInput/DataOutput. Me gustaría reutilizar mi serialización personalizada sin escribir un proxy personalizado para ByteBuffer.

Respuesta

4

Simplemente envuelva el tampón en ByteArrayInputStream o ByteArrayOutputStream utilizando los put() o wrap() métodos. El problema de tener un ByteBuffer emula directamente un flujo de entrada/salida de datos tiene que ver con no conocer los tamaños de antemano. ¿Qué pasa si hay un rebasamiento?

Lo que se necesita es un ByteBufferOutputStream en el que puede envolver/exponer los comportamientos necesarios. Ejemplos de esto existen; el esquema de serialización Apache avro tiene tal cosa. No es demasiado difícil de hacer tu propio. ¿Por qué no hay uno por defecto? Bueno, no es un mundo perfecto ...

ByteArrayOutputStream backing = new ByteArrayOutputStream(); 
DataOutput foo = new DataOutputStream(backing); 
// do your serialization out to foo 

foo.close(); 
ByteBuffer buffer = ByteBuffer.wrap(backing.toByteArray()); 
// now you've got a bytebuffer... 
+0

+ por mencionar a Avero, parece interesante. – Justin

+0

El rebasamiento en lectura debería arrojar EOFException; el rebasamiento en la escritura sería tratado igual que escribir en un volumen completo (o simplemente lanzar EOF también) – Justin

+0

@Justin: mirando la entrada 'DataOutput', sí, eso podría funcionar bien. Tal vez valga la pena realizar un pequeño experimento para asegurarse de que pueda enviar un proxy 'DataOutput' a un' ByteBuffer' limpiamente y publicar un error en el sitio Oracle o ponerse en contacto con el grupo de expertos nio. Puede ser que estas dos apis tengan como objetivo diferentes niveles de abstracción; No estoy seguro. – andersoj

4

Una mejor manera que funcione con tampones directos también:

class ByteBufferOutputStream extends OutputStream 
{ 
    private final ByteBuffer buffer; 

    public ByteBufferOutputStream(ByteBuffer buffer) 
    { 
     this.buffer = buffer; 
    } 

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

Tenga en cuenta que esto requiere llamar buffer.flip() después de que haya terminado de escribir a antes de que puedas leer de él

Cuestiones relacionadas