2013-02-19 7 views
7

Sto cercando di ridimensionare una parte della mia applicazione di uso frequente e di grandi dimensioni in metodi separati per semplificare la manutenzione.Chiudere lo scanner senza chiudere System.in

Alcuni di questi metodi chiede all'utente per l'input e fa validazione dell'input, quindi ho usato uno scanner e System.in Ma quando chiudo il mio scanner ho anche vicino System.in

Quindi la mia domanda è , posso solo impedire che System.in venga chiuso proteggendolo con CloseShieldInputStream o dovrei semplicemente passare uno Scanner ai metodi?

+0

Si prega di inviare un certo codice ... – nkukhar

+5

non si ha realmente bisogno per chiudere lo scanner? Suggerirei di lasciare che il garbage collector lo gestisca - non c'è modo di chiuderlo senza chiudere l'oggetto sottostante. – ddmps

+0

Il mio metodo dichiara uno scanner, legge e restituisce nextLine(), chiude lo scanner e mi dà un mal di testa nella prossima esecuzione. Se non lo chiudo, Eclipse mi assilla per una potenziale perdita di risorse, sarebbe sicuro ignorarlo? – deepy

risposta

3

Si può semplicemente ignorare vicino implementando decoratrice personalizzato.

public class UnClosableDecorator extends InputStream { 

    private final InputStream inputStream; 

    public UnClosableDecorator(InputStream inputStream) { 
     this.inputStream = inputStream; 
    } 

    @Override 
    public int read() throws IOException { 
     return inputStream.read(); 
    } 

    @Override 
    public int read(byte[] b) throws IOException { 
     return inputStream.read(b); 
    } 

    @Override 
    public int read(byte[] b, int off, int len) throws IOException { 
     return inputStream.read(b, off, len); 
    } 

    @Override 
    public long skip(long n) throws IOException { 
     return inputStream.skip(n); 
    } 

    @Override 
    public int available() throws IOException { 
     return inputStream.available(); 
    } 

    @Override 
    public synchronized void mark(int readlimit) { 
     inputStream.mark(readlimit); 
    } 

    @Override 
    public synchronized void reset() throws IOException { 
     inputStream.reset(); 
    } 

    @Override 
    public boolean markSupported() { 
     return inputStream.markSupported(); 
    } 

    @Override 
    public void close() throws IOException { 
     //do nothing 
    } 
} 

e utilizzarlo nella principale

public static void main(String[] args) throws Exception { 
     System.setIn(new UnClosableDecorator(System.in)); 
} 
+0

Non sarebbe lo stesso che scrivere la mia versione di CloseShieldInputStream? – deepy

+0

Non sono abbastanza sicuro di cosa intendi, ma se devi eseguire alcune azioni con il flusso di input alla chiusura esegui queste azioni nel metodo UnClosableDecorator.close() – nkukhar

+1

CloseShieldInputStream è un flusso proxy che impedisce la chiusura del flusso di input sottostante . http://commons.apache.org/io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html – deepy

1

si potrebbe semplicemente lascia che sia senza chiuderla, è sufficiente impostare la variabile tenuta su null

+0

Con che Eclipse avvisa che lo scanner non viene mai chiuso, è sicuro ignorarlo? – deepy

+0

Penso che sia uno stile di programmazione migliorabile. Il programmatore potrebbe finire per lasciare risorse aperte che devono essere effettivamente chiuse. –

11

Basta usare un FilterInputStream personalizzato anziché System.in:

new FilterInputStream(System.in) { 
    @Override 
    public void close() throws IOException { 
     //don't close System.in! 
    } 
} 
+1

molto più semplice della risposta accettata! Grazie. –

+2

Questo è praticamente il significato di [CloseShieldInputStream] (http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html) e se si finisce questa posizione, potresti voler dare un'altra occhiata al design del tuo software. Una soluzione come questa non dovrebbe essere necessaria a meno che non si stia lavorando con soluzioni di terze parti. (si applica a tutte le risposte qui) – deepy