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