尝试用资源意外关闭资源

时间:2015-02-13 12:03:01

标签: java

我试图在while循环中调用以下方法。第一次,它调用很好,但在第二次循环执行时,它抛出一个IOException

public String getInputString(String prompt){
        System.out.print(prompt);
        String inputLine = null;

        try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))){
            inputLine = br.readLine();
            if(inputLine.length() == 0){
                return null;
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }

        return inputLine;
    }

我收到此IOException:

 java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:325)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at ch5.GameHelper.getInputString(GameHelper.java:14)
    at ch5.SimpleDotComTestDrive.main(SimpleDotComTestDrive.java:19)

另一方面,当我尝试按如下方式执行它时它工作正常:

        try{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            inputLine = br.readLine();
            if(inputLine.length() == 0){
                return null;
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }

这种行为的原因是什么?

1 个答案:

答案 0 :(得分:4)

我怀疑你不止一次打电话给getInputString

第一次,它应该可以正常工作 - 但是你关闭System.in(通过关闭BufferedReader包裹InputStreamReader包裹System.in} ...这意味着您尝试从System.in读取的下一次时间,您将无法阅读。

如果你删除了try-with-resources语句,你仍然可能会遇到问题,因为你将围绕同一个流创建多个读者 - 如果其中一个读取的输入多于实际使用的输入,则不会稍后可用。

我建议您在程序开始时创建BufferedReader包裹InputStreamReader包裹System.in 一次,并使用BufferedReader实例无处不在。