当前位置: 首页 > 知识库问答 >
问题:

如何在不关闭基础系统的情况下关闭扫描仪。在里面

何乐
2023-03-14

如果我关闭一个扫描仪对象,并创建一个新的对象,并尝试读取更多的输入,我将得到NoSuchElementExcema异常。

我的代码工作正常,但是如果我不关闭扫描仪,它会给我一个警告。但是,如果我关闭它以摆脱警告,我也关闭System.in...我如何避免这种情况?

另外,不关闭扫描仪是否有任何后果?

编辑:这是我的代码:

这是NameAddressExists()方法:

public void NameAddressExists() {
    System.out.println("Enter name");
    Scanner sc = new Scanner(System.in);
    String n = sc.next();
    System.out.println("Enter address");
    String a = sc.next();
    int flag = 0;
    for(int i = 0; i < count; i++) {
        if(array[i].name .equals(n) && array[i].address .equals(a)) {
            System.out.println("True");
            flag = 1;
        }
    }
    if(flag != 1) {
        new Agency(n, a);
    }
    sc.close();
}

这是PanNumberExists()方法:

public boolean PanNumberExists() {
    Scanner s = new Scanner(System.in);
    String n = "";
    System.out.println("Enter the 5 digits");
    try {
        n = s.nextLine();
    }catch(Exception e) {
        System.out.println(e);
    }finally {
        s.close();
    }
    if(n  .equals(this.PAN.subSequence(4,9))) {
        return true;
    }
    else {
        return false;
    }
}

从以下main()方法调用这些方法:

public static void main(String args[]) {
    Agency obj1 = new Agency("XYZ", "ABCD");
    Agency obj2 = new Agency("XYZ", "ABCDEFG", "+91083226852521", "ab 1234567", "abcd12345ab");
    // Agency obj3 = new Agency("XYZ", "TSRK", "36", "ab 1234567", "abcd12345ab");
    obj1.NameAddressExists();
    System.out.println(obj2.PanNumberExists());
}

如您所见,我首先调用NameAddressExists()方法,在该方法中,我打开、使用并关闭一个名为“sc”的扫描仪。这工作得很好,给了我正确的输出。接下来,我调用PanNumberExists()方法,在该方法中,我打开另一个名为“s”的扫描仪,并尝试使用它从用户那里获取一些输入。这就是我收到的NoTouchElementException异常的地方。如果我在我的NameAddressExists()方法中将扫描器'sc'保持打开状态,则不会出现此错误。


共有2个答案

谢宸
2023-03-14

您可以使用Decorator模式创建无法关闭的自定义InputStream,然后将其传递给扫描仪

import java.io.IOException;
import java.io.InputStream;

public class PreventClosingInputStream extends InputStream {

    private InputStream inputStream;

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

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

    @Override
    public void close() throws IOException {
        // Don't call super.close();
    }

}

然后,在代码中:

PreventClosingInputStream in = new PreventClosingInputStream(System.in);
Scanner s = new Scanner(in);
// ...
s.close(); // This will never close System.in as there is underlying PreventClosingInputStream with empty close() method

使用资源尝试:

try (PreventClosingInputStream in = new PreventClosingInputStream(System.in);
        Scanner s = new Scanner(in);) {
    // ...
    // resources will be automatically closed except of System.in
}
丌官承
2023-03-14
Scanner scan = new Scanner(new FilterInputStream(System.in) {
    @Override
    public void close() throws IOException {
        // do nothing here ! 
    }
});

或者,通过实现自定义装饰器忽略close()

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

并且在main()中使用时,

public static void main(String[] args) throws Exception {
        System.setIn(new UnClosableDecorator(System.in));
}
 类似资料:
  • 问题内容: 我试图将我的应用程序中较大且经常使用的部分重构为单独的方法,以使其易于维护。 其中一些方法要求用户输入并进行输入验证,因此我使用了Scanner和System.in,但是当我关闭Scanner时,我也关闭了System.in。 所以我的问题是,我只能通过用CloseShieldInputStream屏蔽System.in来防止System.in关闭,还是应该开始将Scanner传递给方

  • 我试图将应用程序中大量且经常使用的部分重新划分为不同的方法,以使其更容易维护。 其中一些方法要求用户输入并进行输入验证,因此我使用了扫描仪和系统。但当我关闭扫描仪时,我也会关闭系统。在里面 所以我的问题是,我只能阻止系统。通过使用CloseShieldInputStream屏蔽它来关闭,还是我应该开始向方法传递一个扫描器?

  • 问题内容: 我正在开发游戏,但扫描仪遇到了一个小问题。我收到了一个从未关闭过的资源泄漏扫描程序。 但是我认为我的扫描仪在没有关闭之前就可以正常工作。但是现在不是。有人可以帮我吗? 问题答案: 我假设您正在使用Java 7,因此会收到编译器警告,当您不关闭资源时,通常应在finally块中关闭扫描程序。 甚至更好:使用新的 Try with resource语句 :

  • 输出为: 输入字符串: WEWEW 输入模式搜索: 线程“main”java.util.NoSuchelementException:在java.util.scanner.nextline(scanner.java:1585) 在org.test.regtest.readline(regtest.java:39) 在org.test.regtest.main(regtest.java:22)

  • 位于java.util.scanner.throwfor(未知源)位于java.util.scanner.next(未知源)的线程“main”java.util.NoSuchelementException中出现异常**** 我多次调用s(扫描器),在第二次调用时出现运行时错误。这是由于关闭扫描仪,并可能再次使用它。我的问题是,每次使用Scanner时,我都会创建一个新的Scanner实例,那么为