简体   繁体   English

多次关闭并打开同一文件错误

[英]Multiple times stream close and open on same file error

I am trying to read input from console using two classes in the same method InputStreamReader and BufferedReader . 我试图在同一方法InputStreamReaderBufferedReader中使用两个类从控制台读取输入。 I have closed the stream of former class and read input again but now using latter class. 我关闭了前一类的流,并再次读取输入,但是现在使用后一类。 It is showing error if I close the former class stream before invoking the BufferedReader stream read() method. 如果我在调用BufferedReader流read()方法之前关闭前一个类流,则会显示错误。 But when closing the InputStreamReader stream at the end of the method, it is working fine. 但是,在方法末尾关闭InputStreamReader流时,它工作正常。

My thoughts are - Since I have closed the stream of the former used class, latter stream is independent of it and thus should not affect the running of code. 我的想法是-由于我已经关闭了前一个使用的类的流,因此后一个流与之无关,因此不应该影响代码的运行。

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

OUTPUT ERROR 输出错误

4 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)

Lets start with this: 让我们以此开始:

isr.close();  //here error occurs

Actually, that is not where the error occurs. 实际上,这不是发生错误的地方。 That is a red herring. 那是一条红鲱鱼。 According to the stacktrace, the exception is actually thrown by the following statement: 根据stacktrace,以下语句实际上引发了异常:

int temp = br.read();

Which makes sense. 有道理。 The isr.close() is closing both the Reader and the input stream that it wraps. isr.close()正在关闭Reader及其包装的输入流。 That input stream is the System.in stream. 该输入流是System.in流。

So, when you then create a second InputStreamReader and BufferedReader you are wrapping a stream that you have previously closed. 因此,当您再创建第二个InputStreamReaderBufferedReader您正在包装以前关闭的流。

Hence, when you try to read from your new readers, you get an exception. 因此,当您尝试向新读者阅读时,您会遇到异常。

Solution: Once closed, the System.in stream will stay closed. 解决方案:关闭后, System.in流将保持关闭状态。 So DON'T close System.in . 所以不要关闭System.in


You asked: 您询问:

Would not input stream be open again at commented Line 1 inside the BufferReader constructor ? 不会在BufferReader构造函数中的注释行1再次打开输入流吗?

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

Short answer: No. 简短答案:不可以。

The new is creating a new InputStreamReader instance that wraps the current value of System.in . new正在创建一个新的InputStreamReader实例,该实例包装System.in的当前值。 In this case, that value is a reference for a FileInputStream object for file descriptor 0 ... which you previously closed. 在这种情况下,该值是先前关闭的文件描述符0 ...的FileInputStream对象的引用。

InputStreamReader isr= new InputStreamReader(System.in);

In the above line, isr is a reference acting as the input stream reader(from input source like keyboard). 在上一行中,isr是充当输入流读取器的引用(来自像键盘这样的输入源)。 So once when you close it, the actual input stream gets closed. 因此,一旦关闭它,实际的输入流就会关闭。 It is not that isr is closed. 不是说isr关闭了。

 InputStreamReader isrp= new InputStreamReader(System.in);

Another reference(isrp) just tries to use that stream which has been previously closed before creating a buffered-reader on the stream, and so no further reading is allowed (as the standard input stream, on System.in, has already been closed). 另一个引用(isrp)只是尝试使用先前在该流上创建缓冲读取器之前已关闭的该流,因此不允许进行进一步的读取(因为System.in上的标准输入流已被关闭) 。

Also, it is just an insane idea to think of using 2 input-streams for the same input source. 同样,想到为同一输入源使用2个输入流只是一个疯狂的想法。 You should use the buffered-reader on the opened input-stream. 您应该在打开的输入流上使用缓冲读取器。 Only after you read your whole-input, then only you should close the stream, finally. 只有在阅读了整个输入之后,才最终应关闭流。

The problem is with 问题出在

isr.close();  //here error occurs

When the line is actually executed, the input stream closes and the buffered reader is not able to find out the closed stream. 当实际执行该行时,输入流关闭,并且缓冲的读取器无法找到关闭的流。 The fix you can do is comment out the close line and execute it after all the computations. 您可以做的修复是在最后一行注释掉并在所有计算之后执行它。 Once an input stream is closed it cannot be reopened again 输入流一旦关闭,便无法再次打开

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM