2012-02-29 21 views
5

Problema muy simple: estoy leyendo desde un SocketChannel y me gustaría escribir los resultados en otro SocketChannel. Estoy usando un objeto Selector, por lo que espero hasta que se pueda leer un SocketChannel, vuelco los datos a un ByteBuffer, y luego, cuando el siguiente SocketChannel se pueda escribir, vuelvo a colocar allí el ByteBuffer. OK hasta ahora. Sin embargo, no parece que haya ninguna forma de "borrar" realmente un ByteBuffer, por lo que no puedo hacer ningún tipo de comprobación para saber cuándo han llegado nuevos datos.Borrado de un ByteBuffer

he probado el método .clear(), pero que al parecer no se borra la memoria intermedia, pero sólo restablece la posición de memoria intermedia a 1.

nunca programa en Java tan desnudo conmigo si esto es un problema con una solución "obvia" ...

Aquí hay un código de ejemplo:

ByteBuffer channel1buf = ByteBuffer.allocate(1024); 
ByteBuffer channel2buf = ByteBuffer.allocate(1024); 

if (key.isReadable()) { 
    if (key.channel().equals(channel1)) { 
     channel1.read(channel2buf); 
    } else if (key.channel().equals(channel2)) { 
     channel2.read(channel1buf); 
    } 
} else if (key.isWritable()) { 
    if (key.channel().equals(channel1) && channel1buf.asCharBuffer().length() > 0) { 
     channel1.write(channel1buf); 
     /* some way to clear channel1buf */ 
    } else /* same idea for channel2... */ 
} 

Gracias!

+0

Debe utilizar los 'ByteBuffer' como adjunto al registrar el canal al selector (tercer parámetro del método regsiter), de esa manera se puede recuperar el archivo adjunto del' SelectionKey' y evitar todo el anidado si las cláusulas . – mike

Respuesta

4

Buffer.clear restablece la posición, sí, y luego puede usar getPosition() > 0 para verificar si algo se ha agregado al búfer después, no ...?

+0

Que casi funciona, sin embargo, el búfer aún tiene los datos antiguos, por lo que imprimirá cualquier desbordamiento. Supongo que podría pasar por el buffer y limpiarlo manualmente, pero eso no parece demasiado elegante. – user1241397

+0

El punto es, ¿por qué te importa si el buffer todavía tiene los datos antiguos? No es como si aclararlo te permitiera GC cualquier cosa. Simplemente no mire nada debajo del 'getPosition()' y debería estar bien ... ¿o hay algo que me falta? –

+0

Bueno, el búfer tiene un tamaño fijo, así que si hago eso eventualmente me quedaré sin espacio en el búfer. – user1241397

4

He resuelto el mismo problema con este código, espero que pueda ayudarlo.

channel1buf.clear(); 
//zerolize buff manually 
channel1buf.put(new byte[1024]); 
channel1buf.clear(); 
+1

O 'Arrays.fill (channel1buf, (byte) 0); channel1buf.clear(); ' –

+1

Pero este tipo de' ZeroMemory() 'para un búfer no es necesario si usas la clase' ByteBuffer' de la manera en que está destinado a ser usado, lo cual es llamando 'flip()' antes leyendo, 'rebobinar()' antes de volver a leer, 'borrar()' o 'compacto()' antes de escribir. – Lumi