Java 如何在不关闭基础System.in的情况下关闭扫描仪?
如果我关闭一个扫描器对象,创建一个新的扫描器对象,并尝试读取更多的输入,我将得到Java 如何在不关闭基础System.in的情况下关闭扫描仪?,java,java.util.scanner,nosuchelementexception,system.in,Java,Java.util.scanner,Nosuchelementexception,System.in,如果我关闭一个扫描器对象,创建一个新的扫描器对象,并尝试读取更多的输入,我将得到NoSuchElementException异常 我的代码工作正常,但如果我不关闭扫描仪,它会给我一个警告。但是,如果我关闭它以消除警告,我也会关闭系统。。。我如何避免这种情况 另外,不关闭扫描仪是否有任何后果 编辑:这是我的代码: 这是NameAddressExists()方法: 这些方法是从以下main()方法调用的: 如您所见,我首先调用NameAddressExists()方法,在该方法中,我打开、使用并关闭
NoSuchElementException
异常
我的代码工作正常,但如果我不关闭扫描仪,它会给我一个警告。但是,如果我关闭它以消除警告,我也会关闭系统。。。我如何避免这种情况
另外,不关闭扫描仪是否有任何后果
编辑:这是我的代码:
这是NameAddressExists()方法:
这些方法是从以下main()方法调用的:
如您所见,我首先调用NameAddressExists()方法,在该方法中,我打开、使用并关闭一个名为“sc”的扫描仪。这工作得很好,给了我正确的输出。接下来,我调用PanNumberExists()方法,在该方法中,我打开另一个名为“s”的扫描仪
,并尝试使用它从用户那里获取一些输入。这就是我收到的NoTouchElementException
异常的地方。如果我在我的NameAddressExists()方法中将扫描器
'sc'保持打开状态,则不会出现此错误
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()中使用时
您可以使用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-with-resources:
try (PreventClosingInputStream in = new PreventClosingInputStream(System.in);
Scanner s = new Scanner(in);) {
// ...
// resources will be automatically closed except of System.in
}
还有其他问题,查看代码会使问题更容易诊断。这不是正常行为。你能展示你的代码吗?至于不关闭扫描仪——冒着被其他用户射击的风险——如果你的程序不大,那也没什么大不了的。但是,关闭你打开的东西来管理内存是很好的。只要在程序的最后一个块中关闭扫描器,你就成功了。另外,你能提供JDK版本和操作系统吗?可能是
public static void main(String[] args) throws Exception {
System.setIn(new UnClosableDecorator(System.in));
}
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
}