Utilities of auto close

Zhong Yu zhong.j.yu at gmail.com
Mon Jun 24 07:54:08 PDT 2013


I agree with you and Jeb that returning a wrapped Stream is better
than returning a Stream that inherits Closeable. The wrapper is more
generic, useful for all types of resources. But I think the task of
triggering clean up should not be on individual resources, but rather
on a enclosing lexical scope. I feel the latter pattern result in more
pleasant code. For example

    try(Scope scope = Scope.newInstance())
    {
        InputStream input = new FileInputStream(src);
        scope.onClose(input::close);

        OutputStream output = new FileOutputStream(dest);
        scope.onClose(output::close);

        ...
    }

It's subjective, of course.

Zhong Yu


On Mon, Jun 24, 2013 at 6:35 AM, Samir Talwar <samir at noodlesandwich.com> wrote:
> I don't like the idea of mutable scopes. This seems like it could introduce
> a whole unnecessary class of bugs. I'd prefer to just replace the
> inheritance with composition using your scope metaphor.
>
>     try (IterableScope<Path> scope = Files.list(dir)) {
>         Stream<Path> entries = scope.stream();
>         // do stuff with entries
>     }
>
>     interface IterableScope<T> extends Iterable<T>, AutoCloseable { }
>
> The name is not so important, but the idea would be to separate the concepts
> of iteration and scoping so that the user has to deal with them both,
> instead of accidentally storing the CloseableStream as a Stream and
> forgetting to close it.
>
> – Samir.
>
> On 21 Jun 2013 15:48, "Zhong Yu" <zhong.j.yu at gmail.com> wrote:
>>
>> EG is discussing the issue of closing a Stream that ties to IO
>> resources, and I'd like to throw in my 2 cents.
>>
>> Background: some new IO methods return Stream of things, for example
>>
>>     class Files
>>         /** return a stream of entries in the dir */
>>         static Stream<Path> list(Path dir);
>>
>> The problem is some IO resources are tied up and they need to be freed
>> as soon as the Stream is no longer used.
>>
>> The current solution is
>>
>>         interface CloseableStream<T> extends Stream<T>, AutoCloseable
>>
>>         static CloseableStream<Path> list(Path dir);
>>
>> EG is discussing an alternative that makes all Streams AutoCloseable
>>
>>         interface Stream<T> extends AutoCloseable
>>
>> Some disagree with that approach, since most Streams do not need to be
>> closed.
>>
>> ==
>> My proposal:
>>
>> It's better to move the business of close() away from Stream to some
>> surrounding constructs. For example:
>>
>>     try(Scope scope = Scope.newInstance())
>>     {
>>         Stream<Path> entries = Files.list(scope, dir);
>>     }
>>
>>    interface Scope extends AutoCloseable
>>     {
>>         void onClose(Runnable action);
>>
>>         void close();
>>     }
>>
>>     static Stream<Path> list(Scope scope, Path dir)
>>     {
>>         ...
>>         scope.onClose( ()->{ free resources } );
>>         ...
>>     }
>>
>>
>> Scope provides generic destructor-like functionality, orthogonal to
>> resource types.
>>
>> Zhong Yu
>>
>


More information about the lambda-dev mailing list