How to check whether an OutputStream is closed
Asked Answered
P

7

37

Is there anyway to check whether an OutputStream is closed without attempting to write to it and catching the IOException?

For example, consider the following contrived method:

public boolean isStreamClosed(OutputStream out){
    if( /* stream isn't closed */){
        return true;
    }else{
        return false;
    }
}

What could you replace /* stream isn't closed */ with?

Portraitist answered 28/12, 2011 at 12:24 Comment(3)
What is the underlying problem you need to solve?Fauteuil
I suspect the OP wants to avoid having to deal with exceptions. ;)Negress
It came about from me thinking defensively about what kind of bad inputs I might receive, but it's more of a hypothetical question, plus the top google result for "java check whether outputstream is closed" points to #2608015 which doesn't seem to actually answer that questionPortraitist
N
39

The underlying stream may not know it its closed until you attempt to write to it (e.g. if the other end of a socket closes it)

The simplest approach is to use it and handle what happens if it closed then, rather than testing it first as well.

No matter what you test, there is always the chance you will get an IOException, so you cannot avoid the exception handling code. Adding this test is likely to complicate the code.

Negress answered 28/12, 2011 at 12:28 Comment(2)
What sets this answer apart from the others is the justification for not having a method such as isClosed(), "The underlying stream may not know it its closed until you attempt to write to it", hence accepted, thanks :)Portraitist
isClosed() is true after you call close() on your end. This is not what most people would like it to do. ;)Negress
B
11

Unfortunately OutputStream API does not have method like isClosed().

So, I know only one clear way: create your class StatusKnowingOutputStream that wraps any other output stream and implements its close() method as following:

public void close() {
    out.close();
    closed = true;
}

Now add method isClosed()

public boolean isClosed() {
    return closed;
}
Broderick answered 28/12, 2011 at 12:29 Comment(3)
However this should never be required in any application. If your own code closes the stream - then it should also handle it's state (closed/open). If however you aquire the stream from some 3-rd party library - it should provide some boolean canIUseTheStream() method.Homeopathic
@bezmax, it might be a bit more difficult to handle its state, let's say if you expect to close it in your business method (you need it closed to send it somewhere else) but you need it to be handled too in a finally clause, so as to have it closed when an exception happens.Inhumation
Its a good thought, but definitely not sufficient for general purpose. There may be the case that the stream is closed from outside the wrapper, such as by the os or the stream provider.Ingraham
M
3
public boolean isStreamClosed(FileOutputStream out){
    try {
        FileChannel fc = out.getChannel();
        return fc.position() >= 0L; // This may throw a ClosedChannelException.
    } catch (java.nio.channels.ClosedChannelException cce) {
        return false;
    } catch (IOException e) {
    }
    return true;
}

This is possible only for a FileOutputStream!

Mycostatin answered 28/12, 2011 at 12:41 Comment(0)
R
2

The OutputStream itself does not support such a method. The Closable interface is defined in a way that once you call close() you are going to dispose of that OutputStream.

Maybe you should revisit a bit the design of the application and check why you're not doing that and you're ending up with a closed OutputStream instance still running around in your application.

Repent answered 28/12, 2011 at 12:29 Comment(0)
S
1

No. If you implement your own, you could write an isClosed method, but if you don't know the concrete class, then no. OutputStream is just an abstract class. Here's it's implementation:

   /**
 * Closes this output stream and releases any system resources 
 * associated with this stream. The general contract of <code>close</code> 
 * is that it closes the output stream. A closed stream cannot perform 
 * output operations and cannot be reopened.
 * <p>
 * The <code>close</code> method of <code>OutputStream</code> does nothing.
 *
 * @exception  IOException  if an I/O error occurs.
 */
public void close() throws IOException {
}
Serg answered 28/12, 2011 at 12:29 Comment(3)
Isn't OutputStream an abstract class, hence it could provide some implementation?Portraitist
Yes, sorry, my bad. It doesn't though.Serg
Yes, a shame it doesn't do something like @Broderick suggests in his answer (https://mcmap.net/q/416216/-how-to-check-whether-an-outputstream-is-closed)Portraitist
I
1

If you're doing this in tests, use mockito Spys, then do a verify

I had a test effectively

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.Test;
import java.io.InputStream;

class MyTest {
    @Test
    public void testInputStreamCloseCalled() throws IOException {
        final InputStream spied = spy(...)
    
        // Do something that should call .close() on the spied InputStream
        spied.close()

        verify(spied, times(1)).close();
    }
}

Where ... is the input stream you're acting upon.

Would work with OutputStreams too.

Ignition answered 20/8, 2020 at 10:17 Comment(0)
F
-2

by using out.checkError()

while(!System.out.checkError()) {
    System.out.println('hi');
}

found it here: How do I get java to exit when piped to head

Four answered 14/8, 2013 at 17:17 Comment(1)
That may work for the System.out PrintStream, and in fact works on any PrintStream, but doesn't work on OutputStreams in general.Decaliter

© 2022 - 2024 — McMap. All rights reserved.