Close Scanner without closing System.in

2019-01-05 06:09发布

I'm trying to re-factor a large and frequently used part of my application into separate methods to make it easier to maintain.

Some of these methods asks the user for input and does input validation, so I've used a Scanner and System.in But when I close my Scanner I also close System.in

So my question is, can I only prevent System.in being closed by shielding it with CloseShieldInputStream or should I just start passing a Scanner to the methods?

3条回答
Juvenile、少年°
2楼-- · 2019-01-05 06:42

you could just let it be without closing it, just set the holding variable to null

查看更多
一纸荒年 Trace。
3楼-- · 2019-01-05 06:44

You can just ignore close by implementing custom decorator.

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

And use it in main

public static void main(String[] args) throws Exception {
        System.setIn(new UnClosableDecorator(System.in));
}
查看更多
Ridiculous、
4楼-- · 2019-01-05 06:58

Simply use a custom FilterInputStream instead of System.in:

new FilterInputStream(System.in) {
    @Override
    public void close() throws IOException {
        //don't close System.in! 
    }
}
查看更多
登录 后发表回答