java - Closing mapped streams - what's the idea? -
it's known javadoc says stream
interface:
streams have basestream.close() method , implement autocloseable, stream instances not need closed after use. generally, streams source io channel (such returned files.lines(path, charset)) require closing. streams backed collections, arrays, or generating functions, require no special resource management. (if stream require closing, can declared resource in try-with-resources statement.)
ok, there methods flatmaptoint
in interface @ same time:
intstream flatmaptoint(function<? super t, ? extends intstream> mapper);
for javadoc specification says:
each mapped stream closed after contents have been placed stream.
so, didn't got idea: if intstream
isn't designed have io channel in source, why closed inside method?
for example, referencepipeline
implementation in way:
try (intstream result = mapper.apply(u)) { if (result != null) result.sequential().foreach(downstreamasint); }
more general question be: should care closing streams intstream
(or descendants) or not? if not, why flatmapto*
care?
edit @tunaki has provided interesting email link. flatmap
, agree should close stream in general case. question special cases: flatmaptoint
, flatmaptolong
, on, don't see necessity of closing streams.
edit-2 @briangoetz appealed here, because cited email, therefore in subject :)
the general rule resource handling whoever responsible closing resource 1 opened it. flatmap
operation operation in stream api opens stream
, operation close it.
quoting this mail, brian goetz said:
to summarize,
flatmap()
operation internally closes stream after done, , reason -- case stream opened operation itself, , therefore should closed operation too. other streams assumed opened caller, , therefore should closed caller.
the example given following. consider
try (stream<path> paths : files.walk(dir)) { paths.flatmap(p -> { try { return files.lines(p); } catch (ioexception e) { throw new uncheckedioexception(e); } }); }
the method reference files::lines
returns stream<string>
of lines of file. when flat mapping operation over, expected opened resource used read file closed. question is: closed what? well, closed flatmap because operation opened stream in first place.
files.lines
returns stream pre-registered close handler closes underlying bufferedreader
. when flatmap operation done, close handler invoked , resources correctly released.
the reason idea backported flatmapto*
operations same: adhering above rule every resource allocated process should closed process.
just show can build intstream
have underlying resource close, consider following stream pipeline each path not flatmapped lines number of character in each line.
try (stream<path> paths : files.walk(dir)) { paths.flatmaptoint(p -> { try { return files.lines(p).maptoint(string::length); } catch (ioexception e) { throw new uncheckedioexception(e); } }); }
Comments
Post a Comment