Likewise, if a stream was not created by your function or class, it should not be closed by it.  Take the simple copyStream utility function below, which was designed to read from one stream and write to another.

/**
 * Note!  This function closes the streams you pass to it.
 */
public void copyStream(InputStream in, OutputStream out)  
       throws IOException
{
    byte[] buf = new byte[2048];
    int bytesRead;
    while( -1 != (bytesRead = in.read(buf,0,buf.length)))
    {
        out.write(buf, 0, bytesRead);
    }
    out.flush();
    in.close();
    out.close();
}

The above code violates the stream ownership rule.  The copyStream() method did not create the streams yet tries to close them without knowing their true purpose.  The comment at the top of the method does not allow the rule to be broken – if for some reason you find yourself needing to break it, there could be a problem with your design.

The copyStream() method cannot know what the real owner of the output stream intends to do with the OutputStream before it is closed – the caller might wish to add more data to the end of the OutputStream first.  The method would be much more useful as below.

public void copyStream(InputStream in, OutputStream out)  
    throws IOException
{
    byte[] buf = new byte[2048];
    int bytesRead;
    while( -1 != (bytesRead = in.read(buf,0,buf.length)))
    {
        out.write(buf, 0, bytesRead);
    }
    out.flush();
}

Summary: If you open a stream you must look after closing it yourself.  If you did not open a stream you are not responsible for closing it and therefore attempting to do so will cause unexpected behaviour.

blog comments powered by Disqus