And I just realized I addressed you by your last name in an earlier message
by mistake. Apologies!

On Friday, August 23, 2013, Remko Popma wrote:

> Thanks Gary! I think that's fine.
> It does look a bit verbose, perhaps we can make a Closer class in the
> helpers package with methods like this:
>
> public static void closeSilent(Closable closable) {
>             try {
>                 if (in != null) {
>                     in.close();
>                 }
>             } catch (final Exception ignored) {
>                 // ignored
>             }
> }
>
> public static void closeWarn(Closable closable, String name) {
>             try {
>                 if (in != null) {
>                     in.close();
>                 }
>             } catch (final Exception ignored) {
>                 LOGGER.warn("Could not close resource: " + name);
>             }
> }
>
>
> On Friday, August 23, 2013, Gary Gregory wrote:
>
>> On Thu, Aug 22, 2013 at 10:02 PM, Gary Gregory <garydgreg...@gmail.com>wrote:
>>
>> On Thu, Aug 22, 2013 at 8:31 PM, Remko Popma <remko.po...@gmail.com>wrote:
>>
>> Sorry if I was unclear. What if creating the Reader fails after the
>> InputStream was created? Then there is no reader object to call close on...
>> In not sure that protecting against a NPE is enough, so I want to close the
>> InputStream in the finally clause. Closing the Reader as well is fine but
>> optional IMO.
>>
>>
>> OK, I can see that.
>>
>> Since each JRE can implement the reader differently, is should also be
>> closed. This would be easier in Java 7 with a try-with-resources, so now I
>> have:
>>
>>
>> Arg, slippery keys. I mean:
>>
>> private String readContents(final URI uri, final Charset charset) throws
>> IOException {
>>         InputStream in = null;
>>         Reader reader = null;
>>         try {
>>             in = uri.toURL().openStream();
>>             reader = new InputStreamReader(in, charset);
>>             final StringBuilder result = new StringBuilder(TEXT_BUFFER);
>>             final char[] buff = new char[PAGE];
>>             int count = -1;
>>             while ((count = reader.read(buff)) >= 0) {
>>                 result.append(buff, 0, count);
>>             }
>>             return result.toString();
>>         } finally {
>>             try {
>>                 if (in != null) {
>>                     in.close();
>>                 }
>>             } catch (final Exception ignored) {
>>                 // ignored
>>             }
>>             try {
>>                 if (reader != null) {
>>                     reader.close();
>>                 }
>>             } catch (final Exception ignored) {
>>                 // ignored
>>             }
>>         }
>>     }
>>
>> Is there a better way to make sure all allocated resources are freed? The
>> Reader contract is clear:
>>
>>     /**
>>      * Closes the stream and releases any system resources associated with
>>      * it.  Once the stream has been closed, further read(), ready(),
>>      * mark(), reset(), or skip() invocations will throw an IOException.
>>      * Closing a previously closed stream has no effect.
>>      *
>>      * @exception  IOException  If an I/O error occurs
>>      */
>>      abstract public void close() throws IOException;
>>
>> So that would be enough but as you point out, building the reader might
>> blow up.
>>
>> In my JRE (Oracle) I see:
>>
>>     public InputStreamReader(InputStream in, Charset cs) {
>>         super(in);
>>         if (cs == null)
>>             throw new NullPointerException("charset");
>>         sd = StreamDecoder.forInputStreamReader(in, this, cs);
>>     }
>>
>> and StreamDecoder is internal code to Oracle so who knows what it does.
>>
>> So... the InputStream should also be closed:
>>
>>     /**
>>      * Closes this input stream and releases any system resources
>> associated
>>      * with the stream.
>>      *
>>      * <p> The <code>close</code> method of <code>InputStream</code> does
>>      * nothing.
>>      *
>>      * @exception  IOException  if an I/O error occurs.
>>      */
>>     public void close() throws IOException {}
>>
>> but in this case the behavior of closing again, is undefined, so it
>> should happen first, before closing the reader, whose contract states that
>> it can handled being closed many times.
>>
>> Can this be done better?
>>
>> Gary
>>
>> Gary
>>
>>
>>
>>
>> On Friday, August 23, 2013, Gary Gregory wrote:
>>
>> Hi Remko,
>>
>> I tried it both ways and it just looks simpler to read this way. The
>> reader passes the close to its wrapped stream. In both cases, you need to
>> close the reader (or the stream) and protect that close with a null guard.
>>
>> Gary
>>
>>
>> On Thu, Aug 22, 2013 at 7:10 PM, Remko Popma <remko.po...@gmail.com>wrote:
>>
>> --
>> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
>> Java Persistence with Hibernate, Second 
>> Edition<http://www.manning.com/bauer3/>
>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>> Spring Batch in Action <http://www.manning.com/templier/>
>> Blog: http://garygregory.wordpress.com
>> Home: http://garygregory.com/
>> Tweet! http://twitter.com/GaryGregory
>>
>

Reply via email to