Point lambdafications in java.io

Jim Mayer jim at pentastich.org
Fri Jun 21 20:48:06 PDT 2013

If you add a close to Stream are you going to make all of the terminal
operations close that stream?  Can we guarantee that the stream will be
closed under all exception conditions?  If not, then I think adding close
may just make things worse.

Consider Files.lines(f).collect(...).  Something needs to make sure the
stream is closed.  Try-with-resources can't help.

If streams are not closeable then something like reads pretty well to me
and has the advantage of making the resource management explicit:

try (InputStream s = new FileInputStream(...)) {
   Something fluid with streams

If there was a way to make sure that all stream terminal operations
effectively did a "try/finally" block that closed the stream it could be
useful, but I don't see how you can protect the stream resources from an
exception being thrown during the creation of the stream pipeline.
Something like:


Where "f()" is a predicate returning function that throws an exception.
How is the stream going to get closed?  The function throws an exception
after "Files.lines" creates its stream but before "collect" is called.

-- Jim
On Jun 21, 2013 10:47 AM, "Brian Goetz" <brian.goetz at oracle.com> wrote:

The stream machinery does not know what resources its source holds; it just
knows Spliterator.  And Spliterator does not have any facility for
releasing resources.

Most streams hold on only to "GC friendly" resources.  But some streams
hold on to "GC resistent" (GCR) resources.  These need help being disposed.
 The attempt at separating them in the type system (CloseableStream) was a

Realistically, whether a stream holds GCR resources or not is not something
that is easily captured in the type system, because its a dynamic property.
 (Like BufferedReader, which wraps another Reader; if the underlying Reader
is GCR then so is the BufferedReader, but this is a purely dynamic
property.  With other cross-cutting concerns like whether a variable is
shared across threads, we basically rely on "the user will know if this
needs to be closed.")

All streams hold resources; having a resource-release mechanism is not
specific to one kind of stream, but more "needed for some streams but still
potentially meaningful for all."

On 6/21/2013 6:03 AM, David Holmes wrote:

> I don't get this at all. I get you can have Streams underpinned by I/O
> streams and that I/O streams have associated resources and need closing.
> But that doesn't imply all Streams have underlying resources and/or need
> closing.
> Why should an attribute specific to one particular kind of Stream
> propagate up into Stream itself yet be meaningless for many kinds of
> Streams ?
> David
> On 19/06/2013 2:05 AM, Brian Goetz wrote:
>> The libraries team added the following methods to java.io and java.nio,
>> with discussion on corelibs-dev:
>> In java.io.BufferedReader:
>>    Stream<String> lines()
>> In java.nio.Files, static methods for:
>>    CloseableStream<Path> list(Path dir) throws IOException;
>>    CloseableStream<Path> walk(Path start, int maxDepth,
>> FileVisitOption... options) throws IOException
>>    CloseableStream<Path> walk(Path start, FileVisitOption... options)
>> throws IOException
>>    CloseableStream<Path> find(Path start,
>>                             int maxDepth,
>>                             BiPredicate<Path, BasicFileAttributes>
>> matcher,
>>                             FileVisitOption... options)
>>          throws IOException
>>    CloseableStream<String> lines(Path path, Charset cs) throws
>> IOException
>> CloseableStream simply extends Stream and AutoCloseable, making it
>> suitable for use with try-with-resources:
>> public interface CloseableStream<T> extends Stream<T>, AutoCloseable {
>>      void close();
>> }
>> Should we consider moving AutoCloseable up to Stream and friends, and
>> get rid of CloseableStream?

More information about the lambda-libs-spec-observers mailing list