guava
guava copied to clipboard
BaseEncoding.encodingStream().close() is non-idempotent
Closeable.close
says:
If the stream is already closed then invoking this method has no effect.
Code:
StringWriter w = new StringWriter();
OutputStream out = BaseEncoding.base64().encodingStream(w);
out.write(0);
out.close();
System.out.println(w);
out.close();
System.out.println(w);
Output:
AA==
AA==A===
Thanks. For our reference, here is the implementation. The simplest thing is probably to mark all methods as synchronized
and track isClosed
in a boolean
field. That may have some performance impact, but I'm not sure we can do better without giving up on thread-safety, which IO streams generally have (though I forget if it's actually guaranteed).
It looks like the problem is just that close
doesn't adjust bitBufferLength
. I don't think thread-safety is required.
Being idempotent is useful; it's very easy to double-close a stream due to ARM blocks and wrapping streams that close their underlying streams.
Synchronization is probably unnecessary. Java I/O streams are generally synchronized, but I've never seen anyone use multiple threads to concurrently read or write a shared stream.
close
doesn't adjustbitBufferLength
@brettkail-wk I assumed you meant that it should go back to zero after closing, even if I'm not sure that it's descriptive of the stream's state.
And while we're at it, @cpovirk, do you think it is possible to tag this repository with topic hacktoberfest
? That would make this PR count towards my 4 PR goal - and my shirt! :shirt: :1234:
Thanks :)
@Saucistophe I have not analyzed the code. I just observed the condition for writing more bytes in close
, and I noticed the similarity in structure to the write
method, which does adjust bitBufferLength
.
I met the same issue, on guava 31.1-jre, is there any plan to have it fixed?