2013-02-19 13 views
7

Ich versuche, einen großen und häufig verwendeten Teil meiner Anwendung in separate Methoden umzuwandeln, um die Pflege zu erleichtern.Scanner schließen, ohne System.in zu schließen

Einige dieser Methoden fordert den Benutzer zur Eingabe und tut Eingabevalidierung, also habe ich einen Scanner und System.in Aber wenn ich meinen Scanner schließe ich auch in der Nähe System.in

Also meine Frage ist verwendet , kann ich nur verhindern, dass System.in geschlossen wird, indem ich es mit CloseShieldInputStream abschirme, oder sollte ich einfach einen Scanner an die Methoden übergeben?

+0

Bitte einen Code schreiben ... – nkukhar

+5

Wollen Sie wirklich schließen müssen der Scanner? Ich würde vorschlagen, den Garbage Collector damit umgehen zu lassen - es gibt keine Möglichkeit, es zu schließen, ohne das darunterliegende Objekt zu schließen. – ddmps

+0

Meine Methode deklariert einen Scanner, liest und gibt nextLine() zurück, schließt den Scanner und bereitet mir beim nächsten Lauf Kopfschmerzen. Wenn ich es nicht schließe, schimpft Eclipse mich über ein mögliches Ressourcenleck, wäre es sicher, das zu ignorieren? – deepy

Antwort

3

Sie in der Nähe von Implementieren von benutzerdefinierten Dekorateur einfach ignorieren können auf null.

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 
    } 
} 

und verwenden Sie es in Haupt

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

Wäre das nicht dasselbe wie das Schreiben meiner eigenen Version von CloseShieldInputStream? – deepy

+0

Ich bin nicht ganz sicher, was meinst du, aber wenn Sie einige Aktionen mit Eingabe-Stream beim Schließen ausführen müssen diese Aktionen in UnClosableDecorator.close() -Methode – nkukhar

+1

CloseShieldInputStream ist ein Proxy-Stream, der verhindert, dass der zugrunde liegende Eingabestream geschlossen wird . http://commons.apache.org/io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html – deepy

1

Sie konntest es einfach nicht zu schließen, aber sein lassen, setzen Sie einfach die Halt Variable

+0

Damit gibt Eclipse eine Warnung aus, dass der Scanner niemals geschlossen wird. Ist dies sicher zu ignorieren? – deepy

+0

Ich denke, es ist ein verbesserungsfähiger Programmierstil. Der Programmierer könnte am Ende offene Ressourcen hinterlassen, die tatsächlich geschlossen werden müssen. –

11

einfach statt System.in einen benutzerdefinierten Filterinput verwenden:

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

viel einfacher als die angenommene Antwort! Vielen Dank. –

+2

Das ist so ziemlich das, was commons '[CloseShieldInputStream] (http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html) tut und wenn Sie am Ende sind In dieser Position möchten Sie vielleicht einen anderen Blick auf das Design Ihrer Software werfen. Eine solche Lösung sollte nicht benötigt werden, es sei denn, Sie arbeiten mit Lösungen von Drittanbietern zusammen. (gilt für alle Antworten hier) – deepy

Verwandte Themen