2013-02-19 28 views
7

Tôi đang cố gắng tái tạo một phần lớn và thường xuyên sử dụng ứng dụng của mình thành các phương pháp riêng biệt để giúp duy trì dễ dàng hơn.Đóng Máy quét mà không đóng System.in

Một số các phương pháp yêu cầu người dùng cho đầu vào và không xác nhận đầu vào, vì vậy tôi đã sử dụng một máy quét và System.in Nhưng khi tôi đóng Scanner của tôi, tôi cũng gần System.in

Vì vậy, câu hỏi của tôi là , tôi có thể chỉ ngăn chặn System.in được đóng cửa bằng cách che chắn nó với CloseShieldInputStream hoặc tôi chỉ nên bắt đầu đi qua một máy quét để các phương pháp?

+0

Xin vui lòng gửi một số mã ... – nkukhar

+5

Bạn có thực sự cần phải đóng Máy quét? Tôi muốn đề nghị để người thu gom rác xử lý nó - không có cách nào để đóng nó lại mà không đóng đối tượng bên dưới. – ddmps

+0

Phương thức của tôi khai báo một Máy quét, đọc và trả về nextLine(), đóng Máy quét và làm tôi đau đầu trong lần chạy tiếp theo. Nếu tôi không đóng nó, Eclipse làm phiền tôi về một sự rò rỉ tài nguyên tiềm ẩn, liệu nó có an toàn để bỏ qua điều đó không? – deepy

Trả lời

3

Bạn chỉ có thể bỏ qua gần bằng cách triển khai trang trí tùy chỉnh.

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

Và sử dụng nó trong chính

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

Điều này có giống với việc viết phiên bản CloseShieldInputStream của riêng tôi không? – deepy

+0

Tôi không hoàn toàn chắc chắn ý của bạn là gì, nhưng nếu bạn cần thực hiện một số hành động với luồng đầu vào khi thực hiện hành động này trong phương thức UnClosableDecorator.close() – nkukhar

+1

CloseShieldInputStream là luồng proxy ngăn chặn luồng đầu vào cơ bản bị đóng . http://commons.apache.org/io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html – deepy

1

bạn chỉ có thể cho phép nó mà không đóng, chỉ cần đặt biến giữ thành không

+0

Với Eclipse đưa ra cảnh báo về máy quét không bao giờ bị đóng, điều này có an toàn để bỏ qua không? – deepy

+0

Tôi nghĩ đó là một phong cách lập trình không thể thay đổi. Các lập trình viên có thể kết thúc rời khỏi tài nguyên mở mà thực sự phải được đóng lại. –

11

Đơn giản chỉ cần sử dụng một FilterInputStream tùy chỉnh thay vì System.in:

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

cách đơn giản hơn câu trả lời được chấp nhận! cảm ơn. –

+2

Điều này khá giống với [CloseShieldInputStream] của commons (http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html) và nếu bạn kết thúc vị trí này, bạn có thể muốn có một cái nhìn khác về thiết kế phần mềm của bạn. Một giải pháp như thế này không cần thiết trừ khi bạn đang làm việc với các giải pháp của bên thứ ba. (áp dụng cho tất cả các câu trả lời ở đây) – deepy