java - BufferedReader 第二次使用返回 null

标签 java file-io

我在 Eclipse 中调试时使用这个自定义类来模拟 system.console。 让我困惑的是 reader = new BufferedReader(new InputStreamReader( System.in)); 在第二次调用 readLine 后返回 null。

我以为是因为我关闭了System.in,但是根据oracle

The close method of InputStream does nothing.

所以现在我很困惑。代码如下:

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();
    }
}

最佳答案

InputStreamclose 方法不执行任何操作,但是 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;
        }
    }

// ....

关于java - BufferedReader 第二次使用返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19594994/

相关文章:

java - 几个测试类后关闭浏览器

java - 如何向每个 JTree 节点添加不同的 JComboBox?

java - 如何从 xsd 模式生成 simple-xml java 注释对象

c++ - 来自 OpenCV 中用户分配数据的 Mat 构造函数

java - 写入从 getResourceAsStream() 返回的文件流

c# - 如何将文本附加到多个文件

java - 仅从 ftp 服务器返回 CSV 文件

Java 解码运行长度分配

java - 缓冲输出写入文件错误

python - 如何在不读取整行或文件的情况下读取标记