2009-06-11 25 views
12

Tengo dos hilos en Java.Cómo saber si un flujo BufferedReader está cerrado

primer hilo se está cerrando un BufferedReader (br.close())

Cuando el segundo hilo hace una lectura sobre el mismo lector consigo un IOException (Stream Closed)

me sale esta excepción, incluso si uso br.ready()

Es Hay una forma de saber si la transmisión ya está cerrada?

+4

Solo por curiosidad, ¿por qué hay varios subprocesos que usan el mismo BufferedReader? –

+0

historia larga señor ... intentando obtener algún código heredado para trabajar ... –

+0

Sólo una nota para tener mucho cuidado de comprobar exactamente qué objeto se está utilizando como monitor con los lectores. –

Respuesta

1

No creo que haya ningún método al que pueda llamar directamente para saber si se cierra una secuencia.

Si realmente necesita tener dos hilos compartiendo este lector, su mejor opción podría ser hacer que la llamada de un hilo vuelva al otro hilo o establecer un indicador para notificarle que la secuencia se ha cerrado para que el otro hilo sepa no intentar leer de ello.

+0

que me pareció el caso también. Revisé el BufferedReader.java en JDK. Hay un método privado ensureOpen que verifica el cierre de transmisión y arroja la excepción de transmisión cerrada. Está comprobando si el lector interno (el utilizado para inicializar el BufferedReader) es nulo. Eso no es accesible afuera. –

1

Si ya ha comenzado una operación de lectura, se le notificará con una excepción IOException de que se ha cerrado una secuencia. Incluso si ya ha llamado a br.ready(), la excepción se produce cuando el código está bloqueado en el método de lectura.

No hay forma de evitar esto. Por el contrario, debe esperar que una operación de lectura arroje una excepción y esté preparado para manejarla adecuadamente.

0

De hecho, mirando a EnsureOpen() comprueba si el objeto en no es nulo. Como es privado, no podemos acceder desde el exterior. Pero si realmente lo necesita, puede usar la reflexión.

BufferedReader myBR = new BufferedReader(new FileReader("c:/somefile.txt")); 
myBR.close(); 

Class c = myBR.getClass(); 
Field in = c.getDeclaredField("in"); 
in.setAccessible(true);   
Object inReader = in.get(myBR); 


if(inReader == null){ 
    System.out.println("is closed"); 
} 
else{ 
    System.out.println("is open"); 
} 
+0

Esto parece funcionar solo. Déjame probar esto en el servidor. –

+1

Cuidado: esto podría ser probablemente lento y podría romperse si las partes internas de la clase cambian. Sugiero usar tu propia 'bandera' para proteger el buffer. –

+0

Dado que la reflexión de Java 1.5 no es tan lenta como lo era antes. –

6

El método ready() arrojará una excepción si se cierra. Pero incluso si agregó un método de verificación cerrada, siempre que se libere el bloqueo entre llamadas (que es para BufferedReader), es posible que el lector esté cerrado cuando lo lea.

veo tres opciones:

  1. Envuelva su llamada de lectura con un bloque try/catch para controlar el caso cerrado.
  2. Cree una subclase de BufferedReader que extienda close() para establecer su propia variable que se puede utilizar para verificar si el lector está cerrado. Esto también requiere anular muchos de los métodos para realizar el comportamiento que desee con un lector cerrado si desea hacer algo más que lanzar el IOException.
  3. Agregue un bloqueo propio y úselo para cerrar el lector (un hilo) y compruebe que el búfer está listo y leído de él. Puede establecer una variable directamente para la comprobación o simplemente agrupar las llamadas ready() y read() en el mismo bloque sincronizado.
1

Otra forma sería extender un BufferedReader en su propia clase, anulando el método close() para indicar si se cerró.

+1

Eso es lo que Kathy dijo en 2 :) –

0

Si solo las cosas que leen en BufferedReader y cierran son sus hilos, me gustaría hacer una sección sincronizada y configurar un poco cuando cierre el lector.Por lo tanto, en cada hilo debe:

  1. Abrir sección sincronizada.
  2. Compruebe si la transmisión no está cerrada ya (verifique la marca).
  3. Leer de la secuencia.
  4. Cerrar transmisión.
  5. Establezca la bandera.
  6. Fin sección sincronizada.

Solo tenga cuidado y evite todo lo que pueda colgar en la sección sincronizada. Básicamente ponga allí solo lo que es necesario, solo lea datos, trátelos más tarde.

Cuestiones relacionadas