Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java BufferedReader在第二次使用时返回空值_Java_File Io - Fatal编程技术网

Java BufferedReader在第二次使用时返回空值

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

在eclipse中调试时,我使用这个自定义类来模拟
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是否有助于减少开销?