Java BufferedReader在第二次使用时返回空值
在eclipse中调试时,我使用这个自定义类来模拟Java BufferedReader在第二次使用时返回空值,java,file-io,Java,File Io,在eclipse中调试时,我使用这个自定义类来模拟system.console。 让我困惑的是reader=newbufferedreader(newinputstreamreader( 系统(in),返回null 我以为是因为我关闭了System.in,但根据 InputStream的close方法不起任何作用 所以现在我被难住了。代码如下: public class CustomConsole { public String readLine(String format, Objec
system.console
。
让我困惑的是reader=newbufferedreader(newinputstreamreader(
系统(in),第二次调用readLine
后,code>返回null
我以为是因为我关闭了System.in,但根据
InputStream的close方法不起任何作用
所以现在我被难住了。代码如下:
public class CustomConsole {
public String readLine(String format, Object... args) {
if (System.console() != null) {
return System.console().readLine(format, args);
}
BufferedReader reader = null;
String line = null;
try {
System.out.print(String.format(format, args));
reader = new BufferedReader(new InputStreamReader(
System.in));
line = reader.readLine();
} catch (IOException e) {
Logger.fatal(e.getMessage());
System.exit(-1);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
Logger.error("CustomConsole.readLine(): BufferedReader could not be closed");
e.printStackTrace();
}
} else {
Logger.error("CustomConsole.readLine(): BufferedReader is null");
}
}
return line;
}
public String readLine() {
return readLine("", "");
}
public char[] readPassword(String format, Object... args) {
if (System.console() != null) return System.console().readPassword(format, args);
return this.readLine(format, args).toCharArray();
}
}
InputStream
的close
方法什么都不做,但是InputStream
可以被子类化,这个子类可以实现close
成为任何东西。例如,BufferedInputStream
就是这种情况,在我的机器上,它是System.in
的类型
当您关闭阅读器时,您将关闭所有底层资源,从而关闭System.in
。之后什么也看不见
要解决这个问题,您只需删除完全关闭读取器的代码,就可以了。每次重新创建一个BufferedReader,然后将其存储为CustomConsole
的一个字段,并在下次重新使用它,这似乎有些奇怪。无论如何,您永远都不需要关闭它,因为它只是System.in的包装器,由系统处理
以这种精神重写你的课程会产生如下结果:
public class CustomConsole {
private BufferedReader reader;
public String readLine(String format, Object... args) {
if (System.console() != null) {
return System.console().readLine(format, args);
}
if (reader == null) {
reader = new BufferedReader(new InputStreamReader(System.in));
}
try {
return reader.readLine();
} catch (IOException e) {
Logger.fatal(e.getMessage());
System.exit(-1);
return null;
}
}
// ....
public class CustomConsole {
private BufferedReader reader;
public String readLine(String format, Object... args) {
if (System.console() != null) {
return System.console().readLine(format, args);
} else if (reader == null) {
reader = new BufferedReader(new InputStreamReader(
System.in));
}
return reader.readLine();
...
InputStream是一个抽象类。in将为您提供InputStream子类的对象,该子类可能以不同方式实现close方法
如何修改类以拥有一个字段来保存您创建的BufferedReader?大概是这样的:
public class CustomConsole {
private BufferedReader reader;
public String readLine(String format, Object... args) {
if (System.console() != null) {
return System.console().readLine(format, args);
}
if (reader == null) {
reader = new BufferedReader(new InputStreamReader(System.in));
}
try {
return reader.readLine();
} catch (IOException e) {
Logger.fatal(e.getMessage());
System.exit(-1);
return null;
}
}
// ....
public class CustomConsole {
private BufferedReader reader;
public String readLine(String format, Object... args) {
if (System.console() != null) {
return System.console().readLine(format, args);
} else if (reader == null) {
reader = new BufferedReader(new InputStreamReader(
System.in));
}
return reader.readLine();
...
根据需要添加异常处理代码。你不必关闭读卡器。如果我从不关闭BufferedReader,它不会在我的程序生命结束时导致泄漏吗?有两件事需要理解:1)标准读卡器/输入流的所有close()
方法都是另一个的包装器,只需关闭底层读卡器/流即可。因此,只有使用该系统的最后一个流实际上值得关闭。因为在你的例子中是System.in,这已经由JVM负责了。感谢你为我澄清了这一点2)无论如何,在你的程序结束时,JVM停止,操作系统收回它使用的所有东西,所以实际上在程序结束时从来没有资源泄漏,从某种意义上说,现在已经没有程序可以在资源上持有句柄了。一般来说,关闭它是一种很好的做法,如果您在一个长期运行的程序中创建了很多短期读取器,这是必不可少的。如果我在一个长期运行的程序中创建了很多短期读取器,那么制作private BufferedReader
static是否有助于减少开销?