-1

Hello World!, I have a question regarding the close() method of the Input Stream class. Here is my code ->

public class Main{
    InputStream consoleInputStream = System.in;
    byte[] bytes = new byte[2];

    consoleInputStream.read(bytes); // I gave the input --> abcdefghij and then enter key(line feed). 
                                    // Hence, abcdefghij and line feed(ASCII - 10) have all entered into consoleInputStream object. 
                                    // The first two bytes i.e. a and b have entered into bytes array.

    for(int i = 0; i < bytes.length; i++){
        System.out.print((char)bytes[i]); // it should print ab
    }

    consoleInputStream.skip(2); // should skip the next two bytes i.e. cd

    consoleInputStream.close(); // closes the connection with console.
                                // I am drawing analogy with the fileInputStream close()

    consoleInputStream.read(bytes); // should read the next two bytes from the consoleInputStream object i.e. e and f, and store them in bytes array.
                                    // Although the stream is closed i.e. connection with the console is closed but the stream already has these characters.

     for(int i = 0; i < bytes.length; i++){
        System.out.print((char)bytes[i]); // should print ef
    }
}

Line by line I have written what I feel should happen. But the program when ran raised exception as follows ->

java.io.IOException: Stream closed

When I initially enter abcdefghij through the console, do all of these characters go into the consoleInputStream object. What I feel is it should. This is because the skip() method works fine i.e. it skips the next two bytes. Hence the consoleInputStream object must have all the characters inside.

But if this happens why do I get exception when I try to read something from the consoleInputStream object after closing it. If the stream already has these characters inside it, it shouldn't matter if the connection with the console is closed or not.

I have just started working with the streams and I want to be conceptually strong in it. Can anybody explain what exactly happens under the hood and where am I conceptually wrong??

Summi
  • 63
  • 8
  • 1
    Calling `close` on a stream should be, literally, the last thing you do. Trying to do anything on a stream after it is closed will lead to this exception. – Joe C Jul 02 '17 at 14:39
  • 1
    Also, you should _never_ close `System.in`. – Joe C Jul 02 '17 at 14:39
  • Why would you assign `InputStream consoleInputStream = System.in;` when you already have the variable `System.in;`? – Lew Bloch Jul 02 '17 at 14:46
  • Thanks Joe. I got your point :) But please Can you tell me what close() method actually does, releases any system resources associated with the stream right. If that is so even when I have called the close method on it, the stream still exists and so the characters inside it. Then why does it raises an exception? – Summi Jul 02 '17 at 14:50
  • 1
    The documentation for `InputStream.read()` says it will throw an exception if the stream has been closed. This behaviour should not be a surprise. – Andy Turner Jul 02 '17 at 14:54
  • When you create a InputStream you tell the JVM to reserve some space in memory. When you set the System.in to the InputStream you tell the JVM to get all the information received in the System Input and send it to your InputStream. After calling close on input stream you cut the connection between the InputStream object and the system input. After the connection is closed, you can not read more information from the System Input, but the Input Stream object still exists. – Gustavo Tavares Jul 02 '17 at 15:04
  • The important point is: I you keep the stream open, the connection between the object and the system input is still valid. And this connection consumes resources from your host. No only memory but resources pointers. – Gustavo Tavares Jul 02 '17 at 15:05
  • “what exactly happens under the hood” is irrelevant. Closing means closing, point. When you close a stream, you can’t read from it afterwards. If you still do it, it throws an exception, because it knows that it has been closed and it was programmed to throw an exception in that case. The exception message could have been `"I told you so"` or `"RTFM"` instead of `"Stream closed"`… – Holger Jul 07 '17 at 07:18
  • Thanks Holger and Gustavo. I got your point very well. So basically, it is programmed to do in that way and you are not allowed to do it. Yes that's simple! Maybe I was overthinking...Anyways, thanks again :) – Summi Jul 08 '17 at 08:38

1 Answers1

0

You need to read javadoc first. InputStream is represent connection to something underlying system related in most cases, after close stream any system rosources associated with this stream are released, and this object not still valid after you invoke that method.

fxrbfg
  • 1,756
  • 1
  • 11
  • 17