The reader should be closed when a Stream
is used in a try-with-resources.
Given this:
try(Stream<String> lines = new BufferedReader(reader).lines()) {
return lines.map(it -> trim ? it.trim() : it)
.collect(Collectors.toList());
}
... the reader is not being closed??
This test fails:
AtomicBoolean closed = new AtomicBoolean(false);
Reader r = new StringReader(" Line1 \n Line2") {
@Override
public void close() {
super.close();
closed.set(true);
}
};
try(Stream<String> lines = new BufferedReader(r).lines()) {
lines.map(it -> trim ? it.trim() : it)
.collect(Collectors.toList());
}
assertTrue("Reader was not closed.",closed.get());
I haven't actually used try-resources syntax. Wish my answer makes sense.
From my understanding, auto-close is closing the resource declared at the statement, nothing else.
Therefore, try(Stream<String> lines = new BufferedReader(r).lines()) {
is simply closing lines
, but not that buffered reader that have no variable assigned.
If you are intended to close both the buffered reader and the stream (do you really need to close the stream anyway?), iirc, you can have multiple lines in the try statement:
try (BufferedReader br = new BufferedReader(r);
Stream<String> lines = br.lines()) {
//....
}
somethings like that. (Haven't tried to compile that, wish it works :P)
Although it is not an immediate answer to your question it ensures that all resources are closed afterwards.
Inspired by Guava's CharSource.lines()
implementation that uses a close handler Stream.onClose(Runnable)
to close the corresponding BufferedReader when the processed stream was closed and
the characteristic of Stream.flatMap(...)
(thanks to this trick)
to call
BaseStream.close()
after its contents have been placed into this stream.
you could get a stream of lines that will be autoclosed after a terminal operation.
Stream<String> lines = lines(reader);
// ..
Stream<String> lines(Reader reader) {
BufferedReader br = new BufferedReader(reader);
Stream<String> lines = br.lines()
.onClose(() -> {
try {
br.close();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
return Stream.of(lines).flatMap(s -> s); // Autocloseable exploit of Stream.flatMap()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With