On Fri, Aug 23, 2013 at 12:21 AM, Remko Popma <remko.po...@gmail.com> wrote:

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


It's all good :)

Gary

>
>
> 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
>>>
>>


-- 
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