2009-06-11 14 views
12

Ho due thread in Java.Come sapere se un flusso BufferedReader è chiuso

primo thread sta chiudendo un BufferedReader (br.close())

Quando il secondo thread fa una lettura sullo stesso lettore di ottengo un IOException (Stream Closed)

ottengo questa eccezione, anche se io uso br.ready()

Is c'è un modo per sapere se lo stream è già chiuso?

+4

Solo per curiosità, perché più thread utilizzano lo stesso BufferedReader? –

+0

long story signore ... per ottenere il codice legacy per funzionare ... –

+0

Solo una nota per fare molta attenzione a controllare esattamente quale oggetto viene usato come monitor con i lettori. –

risposta

1

Non penso che ci sia un metodo che è possibile chiamare direttamente per dire se uno stream è chiuso.

Se è davvero necessario avere due thread che condividono questo lettore, l'opzione migliore potrebbe essere quella di richiamare l'altro thread all'altro thread o impostare un flag per notificarlo che lo stream è stato chiuso in modo che l'altro thread sappia non provare a leggere da esso.

+0

mi è sembrato il caso anche a me. Ho controllato BufferedReader.java in JDK. Esiste un metodo secureApen privato che controlla la chiusura del flusso e genera l'eccezione Stream Closed. Sta controllando se il Reader interno (quello usato per inizializzare BufferedReader) è nullo. Questo non è accessibile al di fuori. –

1

Se è già stata avviata un'operazione di lettura, verrà inviata una notifica con IOException per la chiusura di uno stream. Anche se hai già chiamato br.ready(), l'eccezione si verifica quando il codice viene bloccato con il metodo read.

Non c'è modo di evitare questo. Al contrario, dovresti aspettarti che un'operazione di lettura generi un'eccezione e preparati a gestirla in modo appropriato.

0

In effetti, guardando ensureOpen() controlla se l'oggetto nell'oggetto non è nullo. Poiché è privato, non possiamo accedervi dall'esterno. Ma se davvero ne hai bisogno, puoi usare la riflessione.

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

Sembra funzionare da solo. Fammi provare sul server .. –

+1

Attento: potrebbe essere probabilmente lento e potrebbe interrompersi se gli interni della classe cambiano. Suggerisco di usare il proprio "flag" per proteggere il buffer. –

+0

Poiché il riflesso di Java 1.5 non è lento come prima. –

6

Il metodo ready() genera un'eccezione se chiuso. Ma anche se hai aggiunto un metodo di controllo chiuso, fintanto che il blocco viene rilasciato tra le chiamate (che è per BufferedReader), il lettore potrebbe essere chiuso al momento della lettura.

vedo tre opzioni:

  1. Avvolgere la chiamata di lettura con un blocco try/catch per gestire il caso chiuso.
  2. Creare una sottoclasse di BufferedReader che estende close() per impostare la propria variabile che è possibile utilizzare per verificare se il lettore è chiuso. Ciò richiede anche la sovrascrittura di un gran numero di metodi per eseguire qualsiasi comportamento si desideri con un lettore chiuso se si desidera che faccia qualcosa al di là dello IOException.
  3. Aggiungere un blocco e utilizzarlo per chiudere il lettore (un thread) e verificare che il buffer sia pronto e leggere da esso. È possibile impostare una variabile direttamente per il controllo o raggruppare semplicemente le chiamate ready() e read() nello stesso blocco sincronizzato.
1

Un altro modo sarebbe estendere un BufferedReader nella propria classe, ignorando il metodo close() per indicare se era chiuso.

+1

Ecco cosa ha detto Kathy in 2 :) –

0

Se solo le cose che leggono da BufferedReader e chiudono sono le discussioni, vorrei solo fare sezione sincronizzata e impostare un po 'piatto quando si chiude il Reader.Quindi in ogni discussione dovresti:

  1. Apri sezione sincronizzata.
  2. Verificare se il flusso non è già chiuso (controllare la bandiera).
  3. Lettura dallo stream.
  4. Chiudi flusso.
  5. Imposta la bandiera.
  6. Fine sezione sincronizzata.

Basta fare attenzione ed evitare tutto ciò che potrebbe bloccarsi nella sezione sincronizzata. Fondamentalmente messo lì solo ciò che è necessario, solo leggere i dati, elaborarli in un secondo momento.

Problemi correlati