2010-07-12 2 views
11

Sto creando un metodo Java che accetta un singolo InputStream come argomento. Per la comodità di lavorare con un flusso di caratteri-based, avvolgo il previsto InputStream all'inizio della implementazione del metodo come segue:Come evitare di chiudere un InputStream passato al mio metodo che avvolgo nei flussi Reader?

public void doStuff(InputStream inStream) { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); 
    ... 
} 

Dal momento che l'InputStream (inStream) è passato al mio metodo, non lo faccio voglio chiuderlo ... poiché penso che dovrebbe essere la responsabilità del client che chiama il mio metodo (questa supposizione è corretta?). Tuttavia, penso che dovrei chiudere lo BufferedReader che ho creato; ma nel farlo, credo che chiuderà automaticamente tutti gli altri stream composti incluso lo inStream.

Qualcuno vede un modo per me di chiudere il BufferedReader e InputStreamReader che ho creato mentre non chiudendo il InputStream passato al mio metodo? Forse c'è un modo per fare una copia del InputStream fornito prima che lo avvolgo? Grazie

+1

Sei consapevole del fatto che lo streaming non confezionato sarà praticamente inutile? –

+1

È necessario fornire un 'set di caratteri' specifico quando si crea un 'InputStreamReader' piuttosto che ignorarlo e lasciare che venga utilizzata la piattaforma predefinita. – ColinD

+0

Tom, vorresti chiarire cosa intendi con "il flusso non confezionato sarà praticamente inutile"? – user389591

risposta

3

Quello che mi piacerebbe provare sarebbe l'override del metodo close:

BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)){ 
    public void close() throws IOException { 
     synchronized (lock) { 
      if (in == null) 
       return; 
     } 
    } 
}; 
// rest of your code 

po 'pazzo, ma dovrebbe funzionare. Tuttavia, non sono sicuro che questo sia l'approccio migliore.

Penso che questa sia una domanda interessante, quindi spero che qualcuno esperto dia la sua opinione.

4

Personalmente vorrei solo evitare il problema modificando la firma del metodo per richiedere che un BufferedReader (o lettore) essere passati in.

+0

Propaga la creazione di BufferedReader al chiamante. Ma cosa succede se il metodo di chiamata ottiene il suo flusso da qualche altra parte, anche tu? –

+1

Hai un buon punto: si potrebbe desiderare di fornire anche una versione basata su 'Reader'. Perché, se qualcuno ottiene un 'InputStream' con una codifica non predefinita, non può utilizzare il metodo basato sul flusso, poiché InputStreamReader utilizza la codifica errata. –

+0

La classe 'java.util.Properties' fornisce entrambi i metodi' load (InputStream inStream) 'e' load (Reader reader) '. Penso che avere entrambe le opzioni disponibili per i possibili clienti della tua classe sia una comodità che può semplificare il codice cliente. Cioè, il client non deve avvolgere un 'InputStream' per ottenere un' Reader' prima di passarlo come argomento al metodo. – user389591

9

Non è necessario per chiudere un BufferedReader o InputStreamReader o probabilmente maggior parte delle implementazioni dei lettori , quando non desideri chiudere il lettore sottostante.

Questi lettori non contengono alcuna risorsa che una chiamata a close() renderebbe gratuita e che il garbage collector non renderebbe comunque gratuito (ad esempio risorse native o valori in variabili statiche) quando si rilascia il riferimento al lettore alla fine del tuo metodo.

I flussi di input sottostanti che comunicano con le risorse native, ad es. FileInputStream o gli stream ottenuti dagli URL devono essere chiusi per liberare quelle risorse native.

Per Writer, c'è una differenza in quello close() di solito chiama flush(). Ma poi, puoi chiamare direttamente lo flush().

+1

Sì, anche se alcuni flussi di compressione (anche se non 'Readers' per quanto ne so) utilizzano risorse native e devono essere chiusi. –

+0

Infatti. Pertanto, quando si desidera concatenare diversi flussi di output, ciascuno dei quali è compresso da solo, in un flusso di output, una delle opzioni consiste nell'eliminare il metodo close come suggerisce @Cristian C. (Qualcosa di simile probabilmente accade quando si usano archivi compressi contenenti diversi file.) –