BufferedReaders跨类读取System.in.

时间:2014-03-03 01:23:23

标签: java bufferedreader ioexception system.in

我想知道为什么在使用

时出现java.io.IOException: Stream closed错误
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

在两个不同的班级中。

设置如下。

public class SomeClass{

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    //br.readSomeStuff
    br.close();

    new SomeOtherClass(); //defo not passing the br along to the new class!

}
public class SomeOtherClass{

    public SomeOtherClass(){
        method():
    }

    private void method(){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in))
        br.readLine();
        // results into an IOEXCEPTION Stream close
    }

}

当我在创建另一个类之后关闭第一个类中的BufferedReader时,问题就消失了。我不明白为什么这会产生问题。我在System.in上创建一个新的BufferedReader,为什么这可能导致流关闭错误?

类似问题here。不解释为什么System.in因某种原因而关闭。

提前致谢!

1 个答案:

答案 0 :(得分:1)

因为当您关闭BufferedReader时,所有底层流都将关闭。这是所有包装和读/写流的类的情况。

这是一种便利,因此您无需浏览已实例化的整个对象集(InputStreamInputStreamReader,最后是BufferedReader)和关闭所有这些。

一个简单的测试将证明这一点:

public static void main(String[] args) throws IOException 
{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    br.close();

    // Will throw IOException
    int i = System.in.read();
}

System.in并不特别;这是一个InputStream。如果说基础流是FileInputStream而不是stdin,则会发生同样的事情:

public static void main(String[] args) throws IOException 
{
    File f = new File("SomeFileName");
    FileInputStream fis = new FileInputStream(f);
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
    br.close();

    // throw IOException
    int i = fis.read();
}

鉴于通常这些构造函数是链接的(就像它们在你的例子中一样),因此必须保留并关闭每个构造函数是非常麻烦的。

想象一下每次想要使用流时都必须执行以下操作:

public static void main(String[] args) throws IOException 
{
    File f = new File("SomeFileName");
    FileInputStream fis = new FileInputStream(f);
    InputStreamReader isr = new InputStreamReader(fis);
    BufferedReader br = new BufferedReader(irs);

    // Use the BufferedReader

    br.close();
    isr.close();
    fis.close();

}