Why stream from BufferedReader::lines is not closing the reader?

Tomasz Kowalczewski tomasz.kowalczewski at gmail.com
Mon Nov 18 12:42:28 UTC 2013


thanks for your answers.

Typically I would agree with Gernot that "Whoever creates a Resource is
responsible for closing it.". My example here might have been little
misleading in this regard.
Reader close() method closes the InputStream that was passed to it (thus
violating this principle) and what I really wanted is to close the Reader
(which in turns closes the input stream).

I still think that it would be more user friendly if classes dealing with
I/O should indicate if and when they (don't) close the stream.

As for Alan's answer:

My motivation was following use case: I am downloading files from remote
service and flatMapping them into lines they contain. Creation of the
Reader was hidden inside the mapper. My code does exactly what you
suggested with wrapping the ::close call and throwing UncheckedIOException.

I hoped to get some guidance in how can I reduce boilerplate even further.
As I see it now everyone will be writing such wrappers themselves.

It is not to say that I don't greatly appreciate all the hard work of all
people involved in lambdification of Java. It's fantastic work you have

On Mon, Nov 18, 2013 at 11:10 AM, Alan Bateman <Alan.Bateman at oracle.com>wrote:

> On 18/11/2013 08:46, Tomasz Kowalczewski wrote:
>> 3. If I want the stream to be closed I need to do:
>> reader.lines().onClose(is::close).doStreamyStuff().collect(...);
>> where *is* is an underlying InputStream.
>> The problem with this code is that ::close throws IOException which is not
>> compatible with Runnable accepted by onClose(); Is there a better way?
>> Some
>> wrapper I can use to inject a call to close?
>>  As you have a reference to the buffered reader it might be simplest to
> use try-with-resources so that the reader (and hence the underlying input
> stream) will be closed, something like:
> try (BufferReader reader = ...) {
>   reader.lines().doStreamyStuff().collect(...);
> }
> Alternatively, if the reader is to a file then you can use Files.lines as
> it returns a Stream that will arrange to close the underlying file when you
> close the stream.
> Otherwise if you really need to really want the stream close to close the
> underlying input stream (or reader more likely) then the runnable will need
> to translate the checked IOException to an unchecked exception. The new
> java.io.UncheckedIOException is probably what you want.
> -Alan.

Tomasz Kowalczewski

More information about the core-libs-dev mailing list