Properly closing Java Process InputStream from getInputStream
Asked Answered
S

5

45

I could not find clarification of this in the documentation. But when we have a Process object and call getInputStream(),

Do we get a new stream that we should explicitly close when we are done with it? or do we get the stream that is already there, associated with the Process, that we should not close, but the Process would take care of closing it?

Basically, how should we interact with the stream we get from Process.getInputStream()? close or not to close?

Standoff answered 17/8, 2011 at 18:34 Comment(0)
M
15

From reading UNIXProcess.java, this is what happens:

We need to distinguish between two states: either process is still alive, or it is dead.

If the process is alive, by closing OutputStream (goes to stdin of the process), you are telling the process that there is no more input for it. By closing InputStreams (stdout, stderr of the process), process is no longer to write to these (it will get SIGPIPE if it tries).

When process dies, Java will buffer remaining data from stdout/stderr, and close all three streams for you (it is running "process reaper" thread, which is notified on process death). Any attempt to write to OutputStream will fail. Reading from InputStream will return buffered data, if any. Closing any of them has no benefit, but also causes no harm. (Underlying file descriptors are closed by this time).

Moniliform answered 20/7, 2016 at 9:4 Comment(2)
Could u back it up? It is interesting subject and you answer have details. Thanks.Laina
Does closing the InputStream definitely clear the buffer? i.e. if the process is dead but there is unread data in the buffer, is this definitely removed from the buffer on closing the InputStream?Untrue
B
11

My first reactions was to close it, you always close streams that you open. I do realize the documentation is not up to par, but since they don't explicitly state do not close that to me means follow good programming practices.

InputStream is = process.getInputStream()
try {
    // your code
} finally {
    try { is.close(); } catch (Exception ignore) {}
}

If you need to make sure this isn't problematic, just write a quick test case where you great from the input stream a few dozen times, each time opening and closing the InputStream.

Bribe answered 17/8, 2011 at 20:20 Comment(1)
IOUtils.closeQuietly(is) will take care of the try { is.close(); } catch(Exception ignore) {}Durnan
S
8

When you call Process.getInputStream() you get an existing input stream that was set up for the process. When the process dies, that input stream does not go away automatically - think of it as a buffer that you can still read from. The process's end of the pipe might be closed, but your end is not. It is your responsibility to close it, though GC will eventually get it.

You should also close the other two: getErrorStream() and getOutputStream().

Solifidian answered 17/8, 2011 at 22:11 Comment(1)
"When the process dies, that input stream does not go away automatically" -- when you start a process, Java is running "process reaper" thread, which closes the local side of such pipes in this case.Edom
I
1

You do not close streams, that you did not open - that's a nasty side effect. If you created the process, kill it first and close streams after that.

Isotropic answered 16/11, 2016 at 19:54 Comment(0)
M
-1

I always close them! I am not 100% sure, but as far as I know if you leave the inputstream open, the file will be open until you close it!! So follow the "standard rules" and close it! follow an example: Process Builder waitFor() issue and Open file limitations

Manichaeism answered 17/8, 2011 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.