【问题标题】:Multiple times stream close and open on same file error多次流关闭和打开同一文件错误
【发布时间】:2016-08-05 22:38:35
【问题描述】:

我正在尝试使用同一方法 InputStreamReaderBufferedReader 中的两个类从控制台读取输入。我已经关闭了前一类的流并再次读取输入,但现在使用后一类。如果我在调用 BufferedReader 流 read() 方法之前关闭前一个类流,则会显示错误。但是在方法结束时关闭 InputStreamReader 流时,它工作正常。

我的想法是 - 由于我已经关闭了前一个使用类的流,后一个流独立于它,因此不应该影响代码的运行。

public static void main(String[] args) throws Exception {


    //File file = new File("D:\\IOSUMIT\\new_file.txt");

    InputStreamReader isr= new InputStreamReader(System.in);

    System.out.println("your input " + (char)isr.read());



    isr.close();  //here error occurs


    InputStreamReader isrp= new InputStreamReader(System.in); // Line 1

    BufferedReader br = new BufferedReader(isrp);
    int temp = br.read();

    System.out.println("your input  Buffered" + (char)temp);



    br.close();

输出错误

4

your input 4Exception in thread "main" java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
    at sun.nio.cs.StreamDecoder.read(Unknown Source)
    at java.io.InputStreamReader.read(Unknown Source)
    at java.io.BufferedReader.fill(Unknown Source)
    at java.io.BufferedReader.read(Unknown Source)
    at IO.Q7.main(Q7.java:60)

【问题讨论】:

  • " 显示错误 "stacktrace?

标签: java file io bufferedreader inputstreamreader


【解决方案1】:

让我们从这个开始:

isr.close();  //here error occurs

实际上,这不是错误发生的地方。那是一条红鲱鱼。根据stacktrace,异常其实是由下面的语句抛出的:

int temp = br.read();

这是有道理的。 isr.close() 正在关闭 Reader 和它包装的输入流。该输入流是System.in 流。

因此,当您创建第二个 InputStreamReaderBufferedReader 时,您正在包装一个您之前关闭的流。

因此,当您尝试阅读新读者的内容时,您会遇到异常。

解决方案:一旦关闭,System.in 流将保持关闭状态。所以不要关闭System.in


你问:

在 BufferReader 构造函数中的注释第 1 行不会再次打开输入流吗?

 InputStreamReader isrp= new InputStreamReader(System.in); // Line 1

简短回答:不。

new 正在创建一个新的InputStreamReader 实例,该实例包含System.in 的当前值。在这种情况下,该值是您之前关闭的文件描述符 0 的 FileInputStream 对象的引用。

【讨论】:

    【解决方案2】:
    InputStreamReader isr= new InputStreamReader(System.in);
    

    在上面的行中,isr 是作为输入流读取器的引用(来自键盘等输入源)。所以一旦你关闭它,实际的输入流就会关闭。并不是 isr 关闭了。

     InputStreamReader isrp= new InputStreamReader(System.in);
    

    另一个引用(isrp) 只是尝试使用之前在流上创建缓冲读取器之前已关闭的流,因此不允许进一步读取(因为 System.in 上的标准输入流已经已关闭)。

    另外,考虑为同一个输入源使用 2 个输入流只是一个疯狂的想法。您应该在打开的输入流上使用缓冲阅读器。只有在您阅读了整个输入之后,您才应该最终关闭流。

    【讨论】:

    • 不会在 BufferReader 构造函数内的注释第 1 行再次打开输入流??。由于引用 isrp 使用的是 new,而不是使用以前的,它会创建一个新的。
    • @angrysumit - 不,正如我已经在第二段中回答的那样,输入流在标准输入(System.in)上关闭,与您尝试在第二行中打开相同。您可以使用任何其他输入(如文件)作为输入流。但是,这个相同的标准输入流不会再次打开。而且,这会导致抛出异常 (java.io.IOException: Stream closed)。
    【解决方案3】:

    问题出在

    isr.close();  //here error occurs
    

    当行实际执行时,输入流关闭,缓冲读取器无法找到关闭的流。您可以做的修复是注释掉关闭行并在所有计算之后执行它。 输入流一旦关闭就无法再次重新打开

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      相关资源
      最近更新 更多